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 # define release_antinspect 0
24 #include "xlockmore.h"
32 # include <X11/Xlib.h>
39 #endif /* HAVE_JWZGLES */
42 #include "gltrackball.h"
44 #define DEF_SHADOWS "True"
48 static XrmOptionDescRec opts[] = {
49 {"-shadows", ".antinspect.shadows", XrmoptionNoArg, "on"},
50 {"+shadows", ".antinspect.shadows", XrmoptionNoArg, "off"}
53 static argtype vars[] = {
54 {&shadows, "shadows", "Shadows", DEF_SHADOWS, t_Bool}
57 static OptionStruct desc[] = {
58 {"-/+shadows", "turn on/off ant shadows"}
61 ENTRYPOINT ModeSpecOpt antinspect_opts = {sizeof opts / sizeof opts[0],
63 sizeof vars / sizeof vars[0],
68 ModStruct antinspect_description =
69 {"antinspect", "init_antinspect", "draw_antinspect", (char *) NULL,
70 "draw_antinspect", "change_antinspect", (char *) NULL, &antinspect_opts,
71 1000, 1, 1, 1, 4, 1.0, "",
72 "draws some ants", 0, NULL};
75 #define Scale4Window 0.3
76 #define Scale4Iconic 0.4
78 #define sqr(A) ((A)*(A))
84 #define ObjAntinspectStrip 0
88 /*************************************************************************/
94 GLXContext *glx_context;
95 trackball_state *trackball;
102 static const float front_shininess[] = {60.0};
103 static const float front_specular[] = {0.7, 0.7, 0.7, 1.0};
104 static const float ambient[] = {0.0, 0.0, 0.0, 1.0};
105 static const float diffuse[] = {1.0, 1.0, 1.0, 1.0};
106 static float position0[] = {0.0, 3.0, 0.0, 1.0};
107 static const float position1[] = {-1.0, -3.0, 1.0, 0.0};
108 static const float lmodel_ambient[] = {0.5, 0.5, 0.5, 1.0};
109 static const float lmodel_twoside[] = {GL_TRUE};
111 static const float MaterialRed[] = {0.6, 0.0, 0.0, 1.0};
112 static const float MaterialOrange[] = {1.0, 0.69, 0.00, 1.0};
113 static const float MaterialGray[] = {0.2, 0.2, 0.2, 1.0};
114 static const float MaterialBlack[] = {0.1, 0.1, 0.1, 0.4};
115 static const float MaterialShadow[] = {0.3, 0.3, 0.3, 0.3};
116 static const float MaterialGray5[] = {0.5, 0.5, 0.5, 0.3};
117 static const float MaterialGray6[] = {0.6, 0.6, 0.6, 1.0};
119 static antinspectstruct *antinspect = (antinspectstruct *) NULL;
126 /* create a matrix that will project the desired shadow */
127 static void shadowmatrix(GLfloat shadowMat[4][4],
128 const GLfloat groundplane[4],
129 const GLfloat lightpos[4])
133 /* find dot product between light position vector and ground plane normal */
134 dot = groundplane[X] * lightpos[X] +
135 groundplane[Y] * lightpos[Y] +
136 groundplane[Z] * lightpos[Z] +
137 groundplane[W] * lightpos[W];
139 shadowMat[0][0] = dot - lightpos[X] * groundplane[X];
140 shadowMat[1][0] = 0.f - lightpos[X] * groundplane[Y];
141 shadowMat[2][0] = 0.f - lightpos[X] * groundplane[Z];
142 shadowMat[3][0] = 0.f - lightpos[X] * groundplane[W];
144 shadowMat[X][1] = 0.f - lightpos[Y] * groundplane[X];
145 shadowMat[1][1] = dot - lightpos[Y] * groundplane[Y];
146 shadowMat[2][1] = 0.f - lightpos[Y] * groundplane[Z];
147 shadowMat[3][1] = 0.f - lightpos[Y] * groundplane[W];
149 shadowMat[X][2] = 0.f - lightpos[Z] * groundplane[X];
150 shadowMat[1][2] = 0.f - lightpos[Z] * groundplane[Y];
151 shadowMat[2][2] = dot - lightpos[Z] * groundplane[Z];
152 shadowMat[3][2] = 0.f - lightpos[Z] * groundplane[W];
154 shadowMat[X][3] = 0.f - lightpos[W] * groundplane[X];
155 shadowMat[1][3] = 0.f - lightpos[W] * groundplane[Y];
156 shadowMat[2][3] = 0.f - lightpos[W] * groundplane[Z];
157 shadowMat[3][3] = dot - lightpos[W] * groundplane[W];
160 static const GLfloat ground[4] = {0.0, 1.0, 0.0, -0.00001};
162 /* simple filled sphere */
163 static Bool mySphere(float radius)
166 GLUquadricObj *quadObj;
168 if((quadObj = gluNewQuadric()) == 0)
170 gluQuadricDrawStyle(quadObj, (GLenum) GLU_FILL);
171 gluSphere(quadObj, radius, 16, 16);
172 gluDeleteQuadric(quadObj);
175 glScalef (radius, radius, radius);
176 glRotatef (90, 1, 0, 0);
177 unit_sphere (16, 16, False);
184 static Bool mySphere2(float radius)
187 GLUquadricObj *quadObj;
189 if((quadObj = gluNewQuadric()) == 0)
191 gluQuadricDrawStyle(quadObj, (GLenum) GLU_LINE);/*GLU_SILHOUETTE);*/
192 gluSphere(quadObj, radius, 16, 8);
193 gluDeleteQuadric(quadObj);
196 glScalef (radius, radius, radius);
197 glRotatef (90, 1, 0, 0);
198 unit_sphere (16, 8, True);
206 static Bool myCone2(float radius)
212 static Bool draw_antinspect_ant(ModeInfo *mi, antinspectstruct * mp,
213 const float *Material, int mono,
214 Bool (*sphere)(float), Bool (*cone)(float))
216 float cos1 = cos(mp->ant_step);
217 float cos2 = cos(mp->ant_step + 2 * Pi / 3);
218 float cos3 = cos(mp->ant_step + 4 * Pi / 3);
219 float sin1 = sin(mp->ant_step);
220 float sin2 = sin(mp->ant_step + 2 * Pi / 3);
221 float sin3 = sin(mp->ant_step + 4 * Pi / 3);
224 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialGray5);
226 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, Material);
227 glEnable(GL_CULL_FACE);
230 if (!((*sphere)(0.18)))
232 glScalef(1, 1 / 1.3, 1);
233 glTranslatef(0.00, 0.30, 0.00);
234 if (!((*sphere)(0.2)))
237 glTranslatef(-0.05, 0.17, 0.05);
238 glRotatef(-90, 1, 0, 0);
239 glRotatef(-25, 0, 1, 0);
240 if (!((*cone)(0.05)))
242 glTranslatef(0.00, 0.10, 0.00);
243 if (!((*cone)(0.05)))
245 glRotatef(25, 0, 1, 0);
246 glRotatef(90, 1, 0, 0);
249 glTranslatef(0.15, -0.65, 0.05);
250 if (!((*sphere)(0.25)))
252 glScalef(1, 1 / 1.3, 1);
254 glDisable(GL_CULL_FACE);
256 glDisable(GL_LIGHTING);
261 glColor3fv(MaterialGray5);
263 glColor3fv(Material);
264 glVertex3f(0.00, 0.30, 0.00);
265 glColor3fv(MaterialGray);
266 glVertex3f(0.40, 0.70, 0.40);
269 glColor3fv(MaterialGray5);
271 glColor3fv(Material);
272 glVertex3f(0.00, 0.30, 0.00);
273 glColor3fv(MaterialGray);
274 glVertex3f(0.40, 0.70, -0.40);
279 glColor3fv(MaterialGray6);
281 glColor3fv(Material);
282 glVertex3f(0.40, 0.70, 0.40);
284 glVertex3f(0.40, 0.70, -0.40);
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 * cos1, 0.15, 0.25);
297 glColor3fv(MaterialGray);
298 glVertex3f(-0.20 + 0.05 * cos1, 0.25 + 0.1 * sin1, 0.45);
302 /* LEFT-CENTER ARM */
303 glBegin(GL_LINE_STRIP);
305 glColor3fv(MaterialGray5);
307 glColor3fv(Material);
308 glVertex3f(0.00, 0.00, 0.18);
309 glVertex3f(0.35 + 0.05 * cos2, 0.00, 0.25);
311 glColor3fv(MaterialGray);
312 glVertex3f(-0.20 + 0.05 * cos2, 0.00 + 0.1 * sin2, 0.45);
318 glBegin(GL_LINE_STRIP);
320 glColor3fv(MaterialGray5);
322 glColor3fv(Material);
323 glVertex3f(0.00, -0.05, 0.18);
324 glVertex3f(0.35 + 0.05 * cos3, -0.15, 0.25);
326 glColor3fv(MaterialGray);
327 glVertex3f(-0.20 + 0.05 * cos3, -0.25 + 0.1 * sin3, 0.45);
331 /* RIGHT-FRONT ARM */
332 glBegin(GL_LINE_STRIP);
334 glColor3fv(MaterialGray5);
336 glColor3fv(Material);
337 glVertex3f(0.00, 0.05, -0.18);
338 glVertex3f(0.35 - 0.05 * sin1, 0.15, -0.25);
340 glColor3fv(MaterialGray);
341 glVertex3f(-0.20 - 0.05 * sin1, 0.25 + 0.1 * cos1, -0.45);
345 /* RIGHT-CENTER ARM */
346 glBegin(GL_LINE_STRIP);
348 glColor3fv(MaterialGray5);
350 glColor3fv(Material);
351 glVertex3f(0.00, 0.00, -0.18);
352 glVertex3f(0.35 - 0.05 * sin2, 0.00, -0.25);
354 glColor3fv(MaterialGray);
355 glVertex3f(-0.20 - 0.05 * sin2, 0.00 + 0.1 * cos2, -0.45);
360 glBegin(GL_LINE_STRIP);
362 glColor3fv(MaterialGray5);
364 glColor3fv(Material);
365 glVertex3f(0.00, -0.05, -0.18);
366 glVertex3f(0.35 - 0.05 * sin3, -0.15, -0.25);
368 glColor3fv(MaterialGray);
369 glVertex3f(-0.20 - 0.05 * sin3, -0.25 + 0.1 * cos3, -0.45);
373 glEnable(GL_LIGHTING);
378 /* only works with 3 right now */
381 static const float MaterialBen[4] = {0.25, 0.30, 0.46, 1.0};
383 static const float* antmaterial[ANTCOUNT] =
384 {MaterialRed, MaterialBen, MaterialOrange};
385 static double antposition[ANTCOUNT] = {0.0, 120.0, 240.0};
386 static const double antvelocity[ANTCOUNT] = {0.3, 0.3, 0.3};
387 static const double antsphere[ANTCOUNT] = {1.2, 1.2, 1.2};
390 static const double antorder[6][ANTCOUNT] = {{0, 1, 2},
398 static Bool draw_antinspect_strip(ModeInfo * mi)
400 antinspectstruct *mp = &antinspect[MI_SCREEN(mi)];
402 int mono = MI_IS_MONO(mi);
404 int ro = (((int)antposition[1])/(360/(2*ANTCOUNT))) % (2*ANTCOUNT);
406 glEnable(GL_TEXTURE_2D);
408 glLightfv(GL_LIGHT0, GL_POSITION, position0);
410 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialGray5);
411 glRotatef(-30.0, 0.0, 1.0, 0.0);
413 glDisable(GL_TEXTURE_2D);
416 /* render ground plane */
417 glBegin(GL_TRIANGLES);
418 glColor4fv(MaterialShadow);
419 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialBlack);
420 glNormal3f(0.0, 1.0, 0.0);
423 glVertex3f(0.0, 0.0, -1.0);
424 glVertex3f(-sqrt(3.0)/2.0, 0.0, 0.5);
425 glVertex3f(sqrt(3.0)/2.0, 0.0, 0.5);
430 for(i = 0; i < 3; ++i) {
431 glRotatef(120.0, 0.0, 1.0, 0.0);
432 glBegin(GL_TRIANGLES);
433 glVertex3f(0.0, 0.0, 1.0 + 3.0);
434 glVertex3f(sqrt(3.0)/2.0, 0.0, -0.5 + 3.0);
435 glVertex3f(-sqrt(3.0)/2.0, 0.0, -0.5 + 3.0);
440 /* first render shadows -- no depth required */
443 shadowmatrix(m, ground, position0);
445 glColor4fv(MaterialShadow);
446 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialShadow);
449 glDisable(GL_LIGHTING);
451 /* display ant shadow */
453 glTranslatef(0.0, 0.001, 0.0);
456 for(i = 0; i < ANTCOUNT; ++i) {
462 glRotatef(antposition[i], 0.0, 1.0, 0.0);
463 glTranslatef(2.4, 0.0, 0.0);
464 glTranslatef(0.0, antsphere[i], 0.0);
465 glRotatef(90.0, 0.0, 1.0, 0.0);
468 glRotatef(10.0, 0.0, 1.0, 0.0);
469 glRotatef(40.0, 0.0, 0.0, 1.0);
470 glTranslatef(0.0, -0.8, 0.0);
471 glRotatef(180.0, 0.0, 1.0, 0.0);
472 glRotatef(90.0, 0.0, 0.0, 1.0);
475 glColor4fv(MaterialShadow);
476 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialShadow);
478 if(antposition[i] > 360.0)
479 antposition[i] = 0.0;
480 draw_antinspect_ant(mi, mp, MaterialShadow, mono, mySphere2, myCone2);
483 glDisable(GL_LIGHTING);
486 glRotatef(-20.0, 1.0, 0.0, 0.0);
487 glRotatef(-mp->ant_step*2, 0.0, 0.0, 1.0);
488 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialShadow);
497 glEnable(GL_LIGHTING);
500 for(j = 0; j < ANTCOUNT; ++j) {
501 /* determine rendering order */
507 glRotatef(antposition[i], 0.0, 1.0, 0.0);
508 glTranslatef(2.4, 0.0, 0.0);
509 glTranslatef(0.0, antsphere[i], 0.0);
510 glRotatef(90.0, 0.0, 1.0, 0.0);
514 glRotatef(10.0, 0.0, 1.0, 0.0);
515 glRotatef(40.0, 0.0, 0.0, 1.0);
516 glTranslatef(0.0, -0.8, 0.0);
517 glRotatef(180.0, 0.0, 1.0, 0.0);
518 glRotatef(90.0, 0.0, 0.0, 1.0);
519 if(antposition[i] > 360.0)
520 antposition[i] = 0.0;
522 draw_antinspect_ant(mi, mp, antmaterial[i], mono, mySphere2, myCone2);
527 glRotatef(-20.0, 1.0, 0.0, 0.0);
528 glRotatef(-mp->ant_step*2, 0.0, 0.0, 1.0);
529 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mono ? MaterialGray5 : antmaterial[i]);
532 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialBlack);
538 /* finally, evolve */
539 antposition[i] += antvelocity[i];
542 /* but the step size is the same! */
545 mp->ant_position += 1;
549 ENTRYPOINT void reshape_antinspect(ModeInfo * mi, int width, int height)
551 double h = (GLfloat) height / (GLfloat) width;
552 antinspectstruct *mp = &antinspect[MI_SCREEN(mi)];
553 mp->linewidth = (width / 512) + 1;
555 glViewport(0, 0, mp->WindW = (GLint) width, mp->WindH = (GLint) height);
556 glMatrixMode(GL_PROJECTION);
559 gluPerspective(45, 1/h, 7.0, 20.0);
561 glMatrixMode(GL_MODELVIEW);
562 glLineWidth(mp->linewidth);
563 glPointSize(mp->linewidth);
566 static void pinit(void)
569 glLightfv(GL_LIGHT0, GL_AMBIENT, ambient);
570 glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse);
571 glLightfv(GL_LIGHT0, GL_POSITION, position0);
572 glLightfv(GL_LIGHT1, GL_AMBIENT, ambient);
573 glLightfv(GL_LIGHT1, GL_DIFFUSE, diffuse);
574 glLightfv(GL_LIGHT1, GL_POSITION, position1);
575 glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient);
576 glLightModelfv(GL_LIGHT_MODEL_TWO_SIDE, lmodel_twoside);
577 glEnable(GL_LIGHTING);
580 glEnable(GL_NORMALIZE);
584 glShadeModel(GL_SMOOTH);
585 glEnable(GL_DEPTH_TEST);
586 glDisable(GL_TEXTURE_2D);
588 glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, front_shininess);
589 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, front_specular);
592 ENTRYPOINT Bool antinspect_handle_event (ModeInfo *mi, XEvent *event)
594 antinspectstruct *mp = &antinspect[MI_SCREEN(mi)];
596 if (gltrackball_event_handler (event, mp->trackball,
597 MI_WIDTH (mi), MI_HEIGHT (mi),
604 ENTRYPOINT void init_antinspect(ModeInfo * mi)
606 antinspectstruct *mp;
608 MI_INIT(mi, antinspect, NULL);
609 mp = &antinspect[MI_SCREEN(mi)];
610 mp->step = NRAND(90);
611 mp->ant_position = NRAND(90);
612 mp->trackball = gltrackball_init (False);
614 if ((mp->glx_context = init_GL(mi)) != NULL) {
615 reshape_antinspect(mi, MI_WIDTH(mi), MI_HEIGHT(mi));
616 glDrawBuffer(GL_BACK);
622 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
625 ENTRYPOINT void draw_antinspect(ModeInfo * mi)
627 antinspectstruct *mp;
629 Display *display = MI_DISPLAY(mi);
630 Window window = MI_WINDOW(mi);
634 mp = &antinspect[MI_SCREEN(mi)];
636 MI_IS_DRAWN(mi) = True;
641 glXMakeCurrent(display, window, *(mp->glx_context));
643 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
647 mi->polygon_count = 0;
649 /* position camera --- this works well, we can peer inside
651 glTranslatef(0.0, 0.0, -10.0);
653 # ifdef HAVE_MOBILE /* Keep it the same relative size when rotated. */
655 GLfloat h = MI_HEIGHT(mi) / (GLfloat) MI_WIDTH(mi);
656 int o = (int) current_device_rotation();
657 if (o != 0 && o != 180 && o != -180)
658 glScalef (1/h, 1/h, 1/h);
659 glRotatef(o, 0, 0, 1);
663 gltrackball_rotate(mp->trackball);
664 glRotatef((15.0/2.0 + 15.0*sin(mp->ant_step/100.0)), 1.0, 0.0, 0.0);
665 glRotatef(30.0, 1.0, 0.0, 0.0);
666 glRotatef(180.0, 0.0, 1.0, 0.0);
668 if (!draw_antinspect_strip(mi)) {
675 if (MI_IS_FPS(mi)) do_fps (mi);
678 glXSwapBuffers(display, window);
684 ENTRYPOINT void change_antinspect(ModeInfo * mi)
686 antinspectstruct *mp = &antinspect[MI_SCREEN(mi)];
688 if (!mp->glx_context)
691 glXMakeCurrent(MI_DISPLAY(mi), MI_WINDOW(mi), *(mp->glx_context));
694 #endif /* !STANDALONE */
697 XSCREENSAVER_MODULE ("AntInspect", antinspect)