2 * Permission to use, copy, modify, and distribute this software and its
3 * documentation for any purpose and without fee is hereby granted,
4 * provided that the above copyright notice appear in all copies and that
5 * both that copyright notice and this permission notice appear in
6 * supporting documentation.
8 * This file is provided AS IS with no warranties of any kind. The author
9 * shall have no liability with respect to the infringement of copyrights,
10 * trade secrets or any patents by this file or any part thereof. In no
11 * event will the author be liable for any lost revenue or profits or
12 * other special, indirect and consequential damages.
14 * Copyright 2004 Blair Tennessy
19 #define DEFAULTS "*delay: 20000 \n" \
22 # define refresh_antinspect 0
23 #include "xlockmore.h"
28 #include "gltrackball.h"
30 #define DEF_SHADOWS "True"
34 static XrmOptionDescRec opts[] = {
35 {"-shadows", ".antinspect.shadows", XrmoptionNoArg, "on"},
36 {"+shadows", ".antinspect.shadows", XrmoptionNoArg, "off"}
39 static argtype vars[] = {
40 {&shadows, "shadows", "Shadows", DEF_SHADOWS, t_Bool}
43 static OptionStruct desc[] = {
44 {"-/+shadows", "turn on/off ant shadows"}
47 ENTRYPOINT ModeSpecOpt antinspect_opts = {sizeof opts / sizeof opts[0],
49 sizeof vars / sizeof vars[0],
54 ModStruct antinspect_description =
55 {"antinspect", "init_antinspect", "draw_antinspect", "release_antinspect",
56 "draw_antinspect", "change_antinspect", (char *) NULL, &antinspect_opts,
57 1000, 1, 1, 1, 4, 1.0, "",
58 "draws some ants", 0, NULL};
61 #define Scale4Window 0.3
62 #define Scale4Iconic 0.4
64 #define sqr(A) ((A)*(A))
70 #define ObjAntinspectStrip 0
74 /*************************************************************************/
80 GLXContext *glx_context;
81 trackball_state *trackball;
88 static const float front_shininess[] = {60.0};
89 static const float front_specular[] = {0.7, 0.7, 0.7, 1.0};
90 static const float ambient[] = {0.0, 0.0, 0.0, 1.0};
91 static const float diffuse[] = {1.0, 1.0, 1.0, 1.0};
92 static float position0[] = {0.0, 3.0, 0.0, 1.0};
93 static const float position1[] = {-1.0, -3.0, 1.0, 0.0};
94 static const float lmodel_ambient[] = {0.5, 0.5, 0.5, 1.0};
95 static const float lmodel_twoside[] = {GL_TRUE};
97 static const float MaterialRed[] = {0.6, 0.0, 0.0, 1.0};
98 static const float MaterialOrange[] = {1.0, 0.69, 0.00, 1.0};
99 static const float MaterialGray[] = {0.2, 0.2, 0.2, 1.0};
100 static const float MaterialBlack[] = {0.1, 0.1, 0.1, 0.4};
101 static const float MaterialShadow[] = {0.3, 0.3, 0.3, 0.3};
102 static const float MaterialGray5[] = {0.5, 0.5, 0.5, 0.3};
103 static const float MaterialGray6[] = {0.6, 0.6, 0.6, 1.0};
105 static antinspectstruct *antinspect = (antinspectstruct *) NULL;
112 /* create a matrix that will project the desired shadow */
113 static void shadowmatrix(GLfloat shadowMat[4][4],
114 const GLfloat groundplane[4],
115 const GLfloat lightpos[4])
119 /* find dot product between light position vector and ground plane normal */
120 dot = groundplane[X] * lightpos[X] +
121 groundplane[Y] * lightpos[Y] +
122 groundplane[Z] * lightpos[Z] +
123 groundplane[W] * lightpos[W];
125 shadowMat[0][0] = dot - lightpos[X] * groundplane[X];
126 shadowMat[1][0] = 0.f - lightpos[X] * groundplane[Y];
127 shadowMat[2][0] = 0.f - lightpos[X] * groundplane[Z];
128 shadowMat[3][0] = 0.f - lightpos[X] * groundplane[W];
130 shadowMat[X][1] = 0.f - lightpos[Y] * groundplane[X];
131 shadowMat[1][1] = dot - lightpos[Y] * groundplane[Y];
132 shadowMat[2][1] = 0.f - lightpos[Y] * groundplane[Z];
133 shadowMat[3][1] = 0.f - lightpos[Y] * groundplane[W];
135 shadowMat[X][2] = 0.f - lightpos[Z] * groundplane[X];
136 shadowMat[1][2] = 0.f - lightpos[Z] * groundplane[Y];
137 shadowMat[2][2] = dot - lightpos[Z] * groundplane[Z];
138 shadowMat[3][2] = 0.f - lightpos[Z] * groundplane[W];
140 shadowMat[X][3] = 0.f - lightpos[W] * groundplane[X];
141 shadowMat[1][3] = 0.f - lightpos[W] * groundplane[Y];
142 shadowMat[2][3] = 0.f - lightpos[W] * groundplane[Z];
143 shadowMat[3][3] = dot - lightpos[W] * groundplane[W];
146 static const GLfloat ground[4] = {0.0, 1.0, 0.0, -0.00001};
148 /* simple filled sphere */
149 static Bool mySphere(float radius)
151 GLUquadricObj *quadObj;
153 if((quadObj = gluNewQuadric()) == 0)
155 gluQuadricDrawStyle(quadObj, (GLenum) GLU_FILL);
156 gluSphere(quadObj, radius, 16, 16);
157 gluDeleteQuadric(quadObj);
163 static Bool mySphere2(float radius)
165 GLUquadricObj *quadObj;
167 if((quadObj = gluNewQuadric()) == 0)
169 gluQuadricDrawStyle(quadObj, (GLenum) GLU_LINE);/*GLU_SILHOUETTE);*/
170 gluSphere(quadObj, radius, 16, 8);
171 gluDeleteQuadric(quadObj);
177 static Bool myCone2(float radius)
183 static Bool draw_antinspect_ant(ModeInfo *mi, antinspectstruct * mp,
184 const float *Material, int mono,
185 Bool (*sphere)(float), Bool (*cone)(float))
187 float cos1 = cos(mp->ant_step);
188 float cos2 = cos(mp->ant_step + 2 * Pi / 3);
189 float cos3 = cos(mp->ant_step + 4 * Pi / 3);
190 float sin1 = sin(mp->ant_step);
191 float sin2 = sin(mp->ant_step + 2 * Pi / 3);
192 float sin3 = sin(mp->ant_step + 4 * Pi / 3);
195 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialGray5);
197 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, Material);
198 glEnable(GL_CULL_FACE);
201 if (!((*sphere)(0.18)))
203 glScalef(1, 1 / 1.3, 1);
204 glTranslatef(0.00, 0.30, 0.00);
205 if (!((*sphere)(0.2)))
208 glTranslatef(-0.05, 0.17, 0.05);
209 glRotatef(-90, 1, 0, 0);
210 glRotatef(-25, 0, 1, 0);
211 if (!((*cone)(0.05)))
213 glTranslatef(0.00, 0.10, 0.00);
214 if (!((*cone)(0.05)))
216 glRotatef(25, 0, 1, 0);
217 glRotatef(90, 1, 0, 0);
220 glTranslatef(0.15, -0.65, 0.05);
221 if (!((*sphere)(0.25)))
223 glScalef(1, 1 / 1.3, 1);
225 glDisable(GL_CULL_FACE);
227 glDisable(GL_LIGHTING);
232 glColor3fv(MaterialGray5);
234 glColor3fv(Material);
235 glVertex3f(0.00, 0.30, 0.00);
236 glColor3fv(MaterialGray);
237 glVertex3f(0.40, 0.70, 0.40);
240 glColor3fv(MaterialGray5);
242 glColor3fv(Material);
243 glVertex3f(0.00, 0.30, 0.00);
244 glColor3fv(MaterialGray);
245 glVertex3f(0.40, 0.70, -0.40);
250 glColor3fv(MaterialGray6);
252 glColor3fv(Material);
253 glVertex3f(0.40, 0.70, 0.40);
255 glVertex3f(0.40, 0.70, -0.40);
260 glBegin(GL_LINE_STRIP);
262 glColor3fv(MaterialGray5);
264 glColor3fv(Material);
265 glVertex3f(0.00, 0.05, 0.18);
266 glVertex3f(0.35 + 0.05 * cos1, 0.15, 0.25);
268 glColor3fv(MaterialGray);
269 glVertex3f(-0.20 + 0.05 * cos1, 0.25 + 0.1 * sin1, 0.45);
273 /* LEFT-CENTER ARM */
274 glBegin(GL_LINE_STRIP);
276 glColor3fv(MaterialGray5);
278 glColor3fv(Material);
279 glVertex3f(0.00, 0.00, 0.18);
280 glVertex3f(0.35 + 0.05 * cos2, 0.00, 0.25);
282 glColor3fv(MaterialGray);
283 glVertex3f(-0.20 + 0.05 * cos2, 0.00 + 0.1 * sin2, 0.45);
289 glBegin(GL_LINE_STRIP);
291 glColor3fv(MaterialGray5);
293 glColor3fv(Material);
294 glVertex3f(0.00, -0.05, 0.18);
295 glVertex3f(0.35 + 0.05 * cos3, -0.15, 0.25);
297 glColor3fv(MaterialGray);
298 glVertex3f(-0.20 + 0.05 * cos3, -0.25 + 0.1 * sin3, 0.45);
302 /* RIGHT-FRONT ARM */
303 glBegin(GL_LINE_STRIP);
305 glColor3fv(MaterialGray5);
307 glColor3fv(Material);
308 glVertex3f(0.00, 0.05, -0.18);
309 glVertex3f(0.35 - 0.05 * sin1, 0.15, -0.25);
311 glColor3fv(MaterialGray);
312 glVertex3f(-0.20 - 0.05 * sin1, 0.25 + 0.1 * cos1, -0.45);
316 /* RIGHT-CENTER ARM */
317 glBegin(GL_LINE_STRIP);
319 glColor3fv(MaterialGray5);
321 glColor3fv(Material);
322 glVertex3f(0.00, 0.00, -0.18);
323 glVertex3f(0.35 - 0.05 * sin2, 0.00, -0.25);
325 glColor3fv(MaterialGray);
326 glVertex3f(-0.20 - 0.05 * sin2, 0.00 + 0.1 * cos2, -0.45);
331 glBegin(GL_LINE_STRIP);
333 glColor3fv(MaterialGray5);
335 glColor3fv(Material);
336 glVertex3f(0.00, -0.05, -0.18);
337 glVertex3f(0.35 - 0.05 * sin3, -0.15, -0.25);
339 glColor3fv(MaterialGray);
340 glVertex3f(-0.20 - 0.05 * sin3, -0.25 + 0.1 * cos3, -0.45);
344 glEnable(GL_LIGHTING);
349 /* only works with 3 right now */
352 static const float MaterialBen[4] = {0.25, 0.30, 0.46, 1.0};
354 static const float* antmaterial[ANTCOUNT] =
355 {MaterialRed, MaterialBen, MaterialOrange};
356 static double antposition[ANTCOUNT] = {0.0, 120.0, 240.0};
357 static const double antvelocity[ANTCOUNT] = {0.3, 0.3, 0.3};
358 static const double antsphere[ANTCOUNT] = {1.2, 1.2, 1.2};
361 static const double antorder[6][ANTCOUNT] = {{0, 1, 2},
369 static Bool draw_antinspect_strip(ModeInfo * mi)
371 antinspectstruct *mp = &antinspect[MI_SCREEN(mi)];
373 int mono = MI_IS_MONO(mi);
375 int ro = (((int)antposition[1])/(360/(2*ANTCOUNT))) % (2*ANTCOUNT);
377 glEnable(GL_TEXTURE_2D);
379 glLightfv(GL_LIGHT0, GL_POSITION, position0);
381 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialGray5);
382 glRotatef(-30.0, 0.0, 1.0, 0.0);
384 glDisable(GL_TEXTURE_2D);
387 /* render ground plane */
388 glBegin(GL_TRIANGLES);
389 glColor4fv(MaterialShadow);
390 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialBlack);
391 glNormal3f(0.0, 1.0, 0.0);
394 glVertex3f(0.0, 0.0, -1.0);
395 glVertex3f(-sqrt(3.0)/2.0, 0.0, 0.5);
396 glVertex3f(sqrt(3.0)/2.0, 0.0, 0.5);
401 for(i = 0; i < 3; ++i) {
402 glRotatef(120.0, 0.0, 1.0, 0.0);
403 glBegin(GL_TRIANGLES);
404 glVertex3f(0.0, 0.0, 1.0 + 3.0);
405 glVertex3f(sqrt(3.0)/2.0, 0.0, -0.5 + 3.0);
406 glVertex3f(-sqrt(3.0)/2.0, 0.0, -0.5 + 3.0);
411 /* first render shadows -- no depth required */
414 shadowmatrix(m, ground, position0);
416 glColor4fv(MaterialShadow);
417 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialShadow);
420 glDisable(GL_LIGHTING);
422 /* display ant shadow */
424 glTranslatef(0.0, 0.001, 0.0);
427 for(i = 0; i < ANTCOUNT; ++i) {
433 glRotatef(antposition[i], 0.0, 1.0, 0.0);
434 glTranslatef(2.4, 0.0, 0.0);
435 glTranslatef(0.0, antsphere[i], 0.0);
436 glRotatef(90.0, 0.0, 1.0, 0.0);
439 glRotatef(10.0, 0.0, 1.0, 0.0);
440 glRotatef(40.0, 0.0, 0.0, 1.0);
441 glTranslatef(0.0, -0.8, 0.0);
442 glRotatef(180.0, 0.0, 1.0, 0.0);
443 glRotatef(90.0, 0.0, 0.0, 1.0);
446 glColor4fv(MaterialShadow);
447 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialShadow);
449 if(antposition[i] > 360.0)
450 antposition[i] = 0.0;
451 draw_antinspect_ant(mi, mp, MaterialShadow, mono, mySphere2, myCone2);
454 glDisable(GL_LIGHTING);
457 glRotatef(-20.0, 1.0, 0.0, 0.0);
458 glRotatef(-mp->ant_step*2, 0.0, 0.0, 1.0);
459 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialShadow);
468 glEnable(GL_LIGHTING);
471 for(j = 0; j < ANTCOUNT; ++j) {
472 /* determine rendering order */
478 glRotatef(antposition[i], 0.0, 1.0, 0.0);
479 glTranslatef(2.4, 0.0, 0.0);
480 glTranslatef(0.0, antsphere[i], 0.0);
481 glRotatef(90.0, 0.0, 1.0, 0.0);
485 glRotatef(10.0, 0.0, 1.0, 0.0);
486 glRotatef(40.0, 0.0, 0.0, 1.0);
487 glTranslatef(0.0, -0.8, 0.0);
488 glRotatef(180.0, 0.0, 1.0, 0.0);
489 glRotatef(90.0, 0.0, 0.0, 1.0);
490 if(antposition[i] > 360.0)
491 antposition[i] = 0.0;
493 draw_antinspect_ant(mi, mp, antmaterial[i], mono, mySphere2, myCone2);
498 glRotatef(-20.0, 1.0, 0.0, 0.0);
499 glRotatef(-mp->ant_step*2, 0.0, 0.0, 1.0);
500 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mono ? MaterialGray5 : antmaterial[i]);
503 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialBlack);
509 /* finally, evolve */
510 antposition[i] += antvelocity[i];
513 /* but the step size is the same! */
516 mp->ant_position += 1;
520 ENTRYPOINT void reshape_antinspect(ModeInfo * mi, int width, int height)
522 double h = (GLfloat) height / (GLfloat) width;
523 antinspectstruct *mp = &antinspect[MI_SCREEN(mi)];
524 mp->linewidth = (width / 512) + 1;
526 glViewport(0, 0, mp->WindW = (GLint) width, mp->WindH = (GLint) height);
527 glMatrixMode(GL_PROJECTION);
530 gluPerspective(45, 1/h, 7.0, 20.0);
532 glMatrixMode(GL_MODELVIEW);
533 glLineWidth(mp->linewidth);
534 glPointSize(mp->linewidth);
537 static void pinit(void)
540 glClearColor(0.0, 0.0, 0.0, 1.0);
542 glLightfv(GL_LIGHT0, GL_AMBIENT, ambient);
543 glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse);
544 glLightfv(GL_LIGHT0, GL_POSITION, position0);
545 glLightfv(GL_LIGHT1, GL_AMBIENT, ambient);
546 glLightfv(GL_LIGHT1, GL_DIFFUSE, diffuse);
547 glLightfv(GL_LIGHT1, GL_POSITION, position1);
548 glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient);
549 glLightModelfv(GL_LIGHT_MODEL_TWO_SIDE, lmodel_twoside);
550 glEnable(GL_LIGHTING);
553 glEnable(GL_NORMALIZE);
557 glShadeModel(GL_SMOOTH);
558 glEnable(GL_DEPTH_TEST);
559 glDisable(GL_TEXTURE_2D);
561 glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, front_shininess);
562 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, front_specular);
565 ENTRYPOINT void release_antinspect(ModeInfo * mi)
568 free((void *) antinspect);
569 antinspect = (antinspectstruct *) NULL;
574 ENTRYPOINT Bool antinspect_handle_event (ModeInfo *mi, XEvent *event)
576 antinspectstruct *mp = &antinspect[MI_SCREEN(mi)];
578 if(event->xany.type == ButtonPress && event->xbutton.button == Button1) {
579 mp->button_down_p = True;
580 gltrackball_start(mp->trackball,
581 event->xbutton.x, event->xbutton.y,
582 MI_WIDTH (mi), MI_HEIGHT (mi));
585 else if(event->xany.type == ButtonRelease &&
586 event->xbutton.button == Button1) {
587 mp->button_down_p = False;
590 else if (event->xany.type == ButtonPress &&
591 (event->xbutton.button == Button4 ||
592 event->xbutton.button == Button5 ||
593 event->xbutton.button == Button6 ||
594 event->xbutton.button == Button7))
596 gltrackball_mousewheel (mp->trackball, event->xbutton.button, 5,
597 !event->xbutton.state);
600 else if(event->xany.type == MotionNotify && mp->button_down_p) {
601 gltrackball_track (mp->trackball,
602 event->xmotion.x, event->xmotion.y,
603 MI_WIDTH (mi), MI_HEIGHT (mi));
610 ENTRYPOINT void init_antinspect(ModeInfo * mi)
612 antinspectstruct *mp;
614 if(antinspect == NULL) {
615 if((antinspect = (antinspectstruct *) calloc(MI_NUM_SCREENS(mi),
616 sizeof (antinspectstruct))) == NULL)
619 mp = &antinspect[MI_SCREEN(mi)];
620 mp->step = NRAND(90);
621 mp->ant_position = NRAND(90);
622 mp->trackball = gltrackball_init ();
624 if ((mp->glx_context = init_GL(mi)) != NULL) {
625 reshape_antinspect(mi, MI_WIDTH(mi), MI_HEIGHT(mi));
626 glDrawBuffer(GL_BACK);
632 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
635 ENTRYPOINT void draw_antinspect(ModeInfo * mi)
637 antinspectstruct *mp;
639 Display *display = MI_DISPLAY(mi);
640 Window window = MI_WINDOW(mi);
644 mp = &antinspect[MI_SCREEN(mi)];
646 MI_IS_DRAWN(mi) = True;
651 glXMakeCurrent(display, window, *(mp->glx_context));
653 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
657 mi->polygon_count = 0;
659 /* position camera --- this works well, we can peer inside
661 glTranslatef(0.0, 0.0, -10.0);
662 gltrackball_rotate(mp->trackball);
663 glRotatef((15.0/2.0 + 15.0*sin(mp->ant_step/100.0)), 1.0, 0.0, 0.0);
664 glRotatef(30.0, 1.0, 0.0, 0.0);
665 glRotatef(180.0, 0.0, 1.0, 0.0);
667 if (!draw_antinspect_strip(mi)) {
668 release_antinspect(mi);
674 if (MI_IS_FPS(mi)) do_fps (mi);
677 glXSwapBuffers(display, window);
683 ENTRYPOINT void change_antinspect(ModeInfo * mi)
685 antinspectstruct *mp = &antinspect[MI_SCREEN(mi)];
687 if (!mp->glx_context)
690 glXMakeCurrent(MI_DISPLAY(mi), MI_WINDOW(mi), *(mp->glx_context));
693 #endif /* !STANDALONE */
696 XSCREENSAVER_MODULE ("AntInspect", antinspect)