http://slackware.bholcomb.com/slackware/slackware-11.0/source/xap/xscreensaver/xscree...
[xscreensaver] / hacks / glx / glschool.c
1 /* glschool.c, Copyright (c) 2005-2006 David C. Lambert <dcl@panix.com>
2  *
3  * Permission to use, copy, modify, distribute, and sell this software and its
4  * documentation for any purpose is hereby granted without fee, provided that
5  * the above copyright notice appear in all copies and that both that
6  * copyright notice and this permission notice appear in supporting
7  * documentation.  No representations are made about the suitability of this
8  * software for any purpose.  It is provided "as is" without express or 
9  * implied warranty.
10  */
11 #include "xlockmore.h"
12 #include "glschool.h"
13
14 #define sws_opts                        xlockmore_opts
15 #define DEFAULTS    "*delay:            20000       \n" \
16                     "*showFPS:      False       \n" \
17                     "*wireframe:    False       \n" \
18
19 #define refresh_glschool                (0)
20 #define release_glschool                (0)
21 #define glschool_handle_event   (0)
22
23 #undef countof
24 #define countof(x) (sizeof((x))/sizeof((*x)))
25
26 static int                      NFish;
27 static Bool                     DoFog;
28 static Bool                     DoDrawBBox;
29 static Bool                     DoDrawGoal;
30 static int                      GoalChgFreq;
31 static float            MinVel;
32 static float            MaxVel;
33 static float            DistExp;
34 static float            AccLimit;
35 static float            AvoidFact;
36 static float            MatchFact;
37 static float            TargetFact;
38 static float            CenterFact;
39 static float            MinRadius;
40 static float            Momentum;
41 static float            DistComp;
42
43 static XrmOptionDescRec opts[] = {
44         { "-nfish",             ".nfish",               XrmoptionSepArg, 0 },
45         { "-fog",               ".fog",                 XrmoptionNoArg, "True" },
46         { "+fog",               ".fog",                 XrmoptionNoArg, "False" },
47         { "-drawgoal",  ".drawgoal",    XrmoptionNoArg, "True" },
48         { "+drawgoal",  ".drawgoal",    XrmoptionNoArg, "False" },
49         { "-drawbbox",  ".drawbbox",    XrmoptionNoArg, "True" },
50         { "+drawbbox",  ".drawbbox",    XrmoptionNoArg, "False" },
51         { "-goalchgf",  ".goalchgf",    XrmoptionSepArg, 0 },
52         { "-maxvel",    ".maxvel",              XrmoptionSepArg, 0 },
53         { "-minvel",    ".minvel",              XrmoptionSepArg, 0 },
54         { "-acclimit",  ".acclimit",    XrmoptionSepArg, 0 },
55         { "-distexp",   ".distexp",             XrmoptionSepArg, 0 },
56         { "-avoidfact", ".avoidfact",   XrmoptionSepArg, 0 },
57         { "-matchfact", ".matchfact",   XrmoptionSepArg, 0 },
58         { "-centerfact",".centerfact",  XrmoptionSepArg, 0 },
59         { "-targetfact",".targetfact",  XrmoptionSepArg, 0 },
60         { "-minradius", ".minradius",   XrmoptionSepArg, 0 },
61         { "-distcomp",  ".distcomp",    XrmoptionSepArg, 0 },
62         { "-momentum",  ".momentum",    XrmoptionSepArg, 0 },
63 };
64
65 static argtype vars[] = {
66         {&NFish,                "nfish",                "NFish",                "100", t_Int},
67         {&DoFog,                "fog",                  "DoFog",                "False", t_Bool},
68         {&DoDrawBBox,   "drawbbox",             "DoDrawBBox",   "True", t_Bool},
69         {&DoDrawGoal,   "drawgoal",             "DoDrawGoal",   "False", t_Bool},
70         {&GoalChgFreq,  "goalchgf",             "GoalChgFreq",  "50",  t_Int},
71         {&MaxVel,               "maxvel",               "MaxVel",               "7.0",  t_Float},
72         {&MinVel,               "minvel",               "MinVel",               "1.0",  t_Float},
73         {&AccLimit,             "acclimit",             "AccLimit",             "8.0",  t_Float},
74         {&DistExp,              "distexp",              "DistExp",              "2.2",  t_Float},
75         {&AvoidFact,    "avoidfact",    "AvoidFact",    "1.5",  t_Float},
76         {&MatchFact,    "matchfact",    "MatchFact",    "0.15",  t_Float},
77         {&CenterFact,   "centerfact",   "CenterFact",   "0.1",  t_Float},
78         {&TargetFact,   "targetfact",   "TargetFact",   "80",  t_Float},
79         {&MinRadius,    "minradius",    "MinRadius",    "30.0",  t_Float},
80         {&Momentum,             "momentum",             "Momentum",             "0.9",  t_Float},
81         {&DistComp,             "distcomp",             "DistComp",             "10.0",  t_Float},
82 };
83
84 ENTRYPOINT ModeSpecOpt glschool_opts = {countof(opts), opts, countof(vars), vars, NULL};
85
86 typedef struct {
87         int                     nColors;
88         int                     rotCounter;
89         int                     goalCounter;
90         Bool            drawGoal;
91         Bool            drawBBox;                       
92         GLuint          bboxList;
93         GLuint          goalList;
94         GLuint          fishList;
95         XColor          *colors;
96         School          *school;
97         GLXContext      *context;
98 } glschool_configuration;
99
100 static glschool_configuration   *scs = NULL;
101
102 ENTRYPOINT void
103 reshape_glschool(ModeInfo *mi, int width, int height)
104 {
105         Bool                                    wire = MI_IS_WIREFRAME(mi);
106         double                                  aspect = (double)width/(double)height;
107         glschool_configuration  *sc = &scs[MI_SCREEN(mi)];
108
109         glXMakeCurrent(MI_DISPLAY(mi), MI_WINDOW(mi), *(sc->context));
110         if (sc->school != (School *)0) {
111                 setBBox(sc->school, -aspect*160, aspect*160, -130, 130, -450, -50.0);
112                 glDeleteLists(sc->bboxList, 1);
113                 createBBoxList(&SCHOOL_BBOX(sc->school), &sc->bboxList, wire);
114         }
115         reshape(width, height);
116 }
117
118 ENTRYPOINT void
119 init_glschool(ModeInfo *mi)
120 {
121         int                                             width = MI_WIDTH(mi);
122         int                                             height = MI_HEIGHT(mi);
123         Bool                                    wire = MI_IS_WIREFRAME(mi);
124         glschool_configuration  *sc;
125
126         if (!scs) {
127                 scs = (glschool_configuration *)calloc(MI_NUM_SCREENS(mi), sizeof(glschool_configuration));
128                 if (!scs) {
129                         perror("init_glschool: ");
130                         exit(1);
131                 }
132         }
133         sc = &scs[MI_SCREEN(mi)];
134
135         sc->drawGoal = DoDrawGoal;
136         sc->drawBBox = DoDrawBBox;
137
138         sc->nColors = 360;
139         sc->context = init_GL(mi);
140         sc->colors = (XColor *)calloc(sc->nColors, sizeof(XColor));
141         make_color_ramp(0, 0,
142                                         0.0, 1.0, 1.0,
143                                         359.0, 1.0, 1.0,
144                                         sc->colors, &sc->nColors,
145                                         False, 0, False);
146
147         sc->school = initSchool(NFish, AccLimit, MaxVel, MinVel, DistExp, Momentum,
148                                                         MinRadius, AvoidFact, MatchFact, CenterFact, TargetFact,
149                                                         DistComp);
150         if (sc->school == (School *)0) {
151                 fprintf(stderr, "couldn't initialize TheSchool, exiting\n");
152                 exit(1);
153         }
154
155         reshape_glschool(mi, width, height);
156
157         initGLEnv(DoFog);
158         initFishes(sc->school);
159         createDrawLists(&SCHOOL_BBOX(sc->school), &sc->bboxList, &sc->goalList, &sc->fishList, wire);
160         computeAccelerations(sc->school);
161 }
162
163 ENTRYPOINT void
164 draw_glschool(ModeInfo *mi)
165 {
166         Window                                  window = MI_WINDOW(mi);
167         Display                                 *dpy = MI_DISPLAY(mi);
168         glschool_configuration  *sc = &scs[MI_SCREEN(mi)];
169
170         if (!sc->context) {
171                 fprintf(stderr, "no context\n");
172                 return;
173         }
174
175         glXMakeCurrent(MI_DISPLAY(mi), MI_WINDOW(mi), *(sc->context));
176
177         if ((sc->goalCounter % GoalChgFreq) == 0)
178                 newGoal(sc->school);
179         sc->goalCounter++;
180
181         sc->rotCounter++;
182         sc->rotCounter = (sc->rotCounter%360);
183
184         applyMovements(sc->school);
185         drawSchool(sc->colors, sc->school, sc->bboxList, sc->goalList, sc->fishList, sc->rotCounter, sc->drawGoal, sc->drawBBox);
186         computeAccelerations(sc->school);
187
188         if (mi->fps_p)
189                 do_fps(mi);
190
191         glFinish();
192         glXSwapBuffers(dpy, window);
193 }
194
195 XSCREENSAVER_MODULE("GLSchool", glschool)