1 /* glschool_gl.c, Copyright (c) 2005-2012 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 
12 #include "sphere.h"
13 #include "glschool_gl.h"
14 #include "sphere.h"
15 #include "tube.h"
16 
17 void
glschool_drawGoal(double * goal,GLuint goalList)18 glschool_drawGoal(double *goal, GLuint goalList)
19 {
20 	glColor3f(1.0, 0.0, 0.0);
21 	glPushMatrix();
22 	{
23 		glTranslatef(goal[0], goal[1], goal[2]);
24 		glColor3f(1.0, 0.0, 0.0);
25 		glCallList(goalList);
26 	}
27 	glPopMatrix();
28 }
29 
30 int
glschool_drawBoundingBox(BBox * bbox,Bool wire)31 glschool_drawBoundingBox(BBox *bbox, Bool wire)
32 {
33   int polys = 0;
34 	double		xMin = BBOX_XMIN(bbox);
35 	double		yMin = BBOX_YMIN(bbox);
36 	double		zMin = BBOX_ZMIN(bbox);
37 
38 	double		xMax = BBOX_XMAX(bbox);
39 	double		yMax = BBOX_YMAX(bbox);
40 	double		zMax = BBOX_ZMAX(bbox);
41 
42 	glFrontFace(GL_CCW);
43 	if (wire) glLineWidth(5.0);
44 
45 	/*  back */
46 	glBegin(wire ? GL_LINE_LOOP : GL_QUADS);
47 	glColor3f(0.0, 0.0, .15);
48 	glVertex3f(xMin, yMin, zMin);
49 	glVertex3f(xMax, yMin, zMin);
50 	glVertex3f(xMax, yMax, zMin);
51 	glVertex3f(xMin, yMax, zMin);
52         polys++;
53 	glEnd();
54 
55 	/* left */
56 	glBegin(wire ? GL_LINE_LOOP : GL_QUADS);
57 	glColor3f(0.0, 0.0, .2);
58 	glVertex3f(xMin, yMin, zMax);
59 	glVertex3f(xMin, yMin, zMin);
60 	glVertex3f(xMin, yMax, zMin);
61 	glVertex3f(xMin, yMax, zMax);
62         polys++;
63 	glEnd();
64 
65 	/* right */
66 	glBegin(wire ? GL_LINE_LOOP : GL_QUADS);
67 	glColor3f(0.0, 0.0, .2);
68 	glVertex3f(xMax, yMin, zMin);
69 	glVertex3f(xMax, yMin, zMax);
70 	glVertex3f(xMax, yMax, zMax);
71 	glVertex3f(xMax, yMax, zMin);
72         polys++;
73 	glEnd();
74 
75 	/* top */
76 	glBegin(wire ? GL_LINE_LOOP : GL_QUADS);
77 	glColor3f(0.0, 0.0, .1);
78 	glVertex3f(xMax, yMax, zMax);
79 	glVertex3f(xMin, yMax, zMax);
80 	glVertex3f(xMin, yMax, zMin);
81 	glVertex3f(xMax, yMax, zMin);
82         polys++;
83 	glEnd();
84 
85 	/* bottom */
86 	glBegin(wire ? GL_LINE_LOOP : GL_QUADS);
87 	glColor3f(0.0, 0.0, .3);
88 	glVertex3f(xMin, yMin, zMax);
89 	glVertex3f(xMax, yMin, zMax);
90 	glVertex3f(xMax, yMin, zMin);
91 	glVertex3f(xMin, yMin, zMin);
92         polys++;
93 	glEnd();
94 
95 	if (wire) glLineWidth(1.0);
96 
97         return polys;
98 }
99 
100 int
glschool_createBBoxList(BBox * bbox,GLuint * bboxList,int wire)101 glschool_createBBoxList(BBox *bbox, GLuint *bboxList, int wire)
102 {
103   int polys = 0;
104 	*bboxList = glGenLists(1);
105 	glNewList(*bboxList, GL_COMPILE);
106 	polys = glschool_drawBoundingBox(bbox, wire);
107 	glEndList();
108         return polys;
109 }
110 
111 void
glschool_createDrawLists(BBox * bbox,GLuint * bboxList,GLuint * goalList,GLuint * fishList,int * fish_polys,int * box_polys,int wire)112 glschool_createDrawLists(BBox *bbox, GLuint *bboxList, GLuint *goalList, GLuint *fishList, int *fish_polys, int *box_polys, int wire)
113 {
114 
115         int faces = 16;
116 
117         *box_polys = 0;
118         *fish_polys = 0;
119 
120         *box_polys += glschool_createBBoxList(bbox, bboxList, wire);
121 
122         *box_polys = 0;
123         *fish_polys = 0;
124 
125 	*goalList = glGenLists(1);
126 	glNewList(*goalList, GL_COMPILE);
127         glScalef (5, 5, 5);
128         *box_polys += unit_sphere (10, 10, wire);
129 	glEndList();
130 
131 	*fishList = glGenLists(1);
132 	glNewList(*fishList, GL_COMPILE);
133         *fish_polys += cone (0, 0, 0,
134                              0, 0, 10,
135                              2, 0,
136                              faces, True, (faces <= 3), /* cap */
137                              wire);
138         glTranslatef (0, 0, -0.3);
139         glScalef (2, 2, 2);
140         glRotatef (90, 1, 0, 0);
141         if (faces > 3)
142           *fish_polys += unit_sphere (faces, faces, wire);
143 	glEndList();
144 }
145 
146 
147 void
glschool_initLights(void)148 glschool_initLights(void)
149 {
150 	GLfloat		amb[4] = {0.1, 0.1, 0.1, 1.0};
151 	GLfloat		dif[4] = {1.0, 1.0, 1.0, 1.0};
152 	GLfloat		spc[4] = {1.0, 1.0, 1.0, 1.0};
153 	GLfloat		pos[4] = {0.0, 50.0, -50.0, 1.0};
154 
155 	glMatrixMode(GL_MODELVIEW);
156 	glLoadIdentity();
157 
158 	glLightfv(GL_LIGHT0, GL_POSITION, pos);
159 	glLightfv(GL_LIGHT0, GL_AMBIENT, amb);
160 	glLightfv(GL_LIGHT0, GL_DIFFUSE, dif);
161 	glLightfv(GL_LIGHT0, GL_SPECULAR, spc);
162 
163 	glEnable(GL_LIGHT0);
164 	glEnable(GL_LIGHTING);
165 }
166 
167 void
glschool_initFog(void)168 glschool_initFog(void)
169 {
170 	GLfloat		fog[4] = {0.0, 0.0, 0.15, 1.0};
171 
172 	glEnable(GL_FOG);
173 	glFogi(GL_FOG_MODE, GL_EXP2);
174 	glFogfv(GL_FOG_COLOR, fog);
175 	glFogf(GL_FOG_DENSITY, .0025);
176 	glFogf(GL_FOG_START, -100);
177 }
178 
179 void
glschool_initGLEnv(Bool doFog)180 glschool_initGLEnv(Bool doFog)
181 {
182 	GLfloat spc[4] = {1.0, 1.0, 1.0, 1.0};
183 
184 	glClearDepth(1.0);
185 	glDepthFunc(GL_LESS);
186 
187 	glEnable(GL_COLOR_MATERIAL);
188 	glMateriali(GL_FRONT, GL_SHININESS, 128);
189 	glMaterialfv(GL_FRONT, GL_SPECULAR, spc);
190 	glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, spc);
191 
192 	glEnable(GL_NORMALIZE);
193 	glEnable(GL_DEPTH_TEST);
194 	glShadeModel(GL_SMOOTH);
195 	glEnable(GL_CULL_FACE);
196 
197 	glschool_initLights();
198 	if (doFog) glschool_initFog();
199 }
200 
201 void
glschool_reshape(int width,int height)202 glschool_reshape(int width, int height)
203 {
204 	GLfloat h = (GLfloat) width / (GLfloat) height;
205 
206 	glViewport (0, 0, (GLint) width, (GLint) height);
207 
208 	glMatrixMode(GL_PROJECTION);
209 	glLoadIdentity();
210 	gluPerspective(60.0, h, 0.1, 451.0);
211 
212 	glMatrixMode(GL_MODELVIEW);
213 	glLoadIdentity();
214 }
215 
216 void
glschool_getColorVect(XColor * colors,int index,double * colorVect)217 glschool_getColorVect(XColor *colors, int index, double *colorVect)
218 {
219 	colorVect[0] = colors[index].red / 65535.0;
220 	colorVect[1] = colors[index].green / 65535.0;
221 	colorVect[2] = colors[index].blue / 65535.0;
222 }
223 
224 void
glschool_drawSchool(XColor * colors,School * s,GLuint bboxList,GLuint goalList,GLuint fishList,int rotCounter,Bool drawGoal_p,Bool drawBBox_p,int fish_polys,int box_polys,unsigned long * polys)225 glschool_drawSchool(XColor *colors, School *s,
226 		   GLuint bboxList, GLuint goalList, GLuint fishList,
227 		   int rotCounter, Bool drawGoal_p, Bool drawBBox_p,
228            int fish_polys, int box_polys, unsigned long *polys)
229 {
230 	double			xVect[3];
231 	double			colorVect[3];
232 	int				i = 0;
233 	double			rotTheta = 0.0;
234 	double			colTheta = 0.0;
235 	Fish			*f = (Fish *)0;
236 	int				nFish = SCHOOL_NFISH(s);
237 	Fish			*theFishes = SCHOOL_FISHES(s);
238 
239 	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
240 
241 	glMatrixMode(GL_MODELVIEW);
242 	glLoadIdentity();
243 
244 	if (drawBBox_p) {
245 		glDisable(GL_LIGHTING);
246 		glCallList(bboxList);
247 		glEnable(GL_LIGHTING);
248                 *polys += box_polys;
249 	}
250 
251 	if (drawGoal_p)	glschool_drawGoal(SCHOOL_GOAL(s), goalList);
252 
253 	for(i = 0, f = theFishes; i < nFish; i++, f++) {
254 		colTheta = glschool_computeNormalAndThetaToPlusZ(FISH_AVGVEL(f), xVect);
255 		rotTheta = glschool_computeNormalAndThetaToPlusZ(FISH_VEL(f), xVect);
256 
257 		if (FISH_IAVGVEL(f,2) < 0.0) colTheta = 180.0 - colTheta;
258 		if (FISH_VZ(f) < 0.0) rotTheta = 180.0 - rotTheta;
259 
260 		glschool_getColorVect(colors, (int)(colTheta+240)%360, colorVect);
261 		glColor3f(colorVect[0], colorVect[1], colorVect[2]);
262 
263 		glPushMatrix();
264 		{
265 			glTranslatef(FISH_X(f), FISH_Y(f), FISH_Z(f));
266 			glRotatef(180.0+rotTheta, xVect[0], xVect[1], xVect[2]);
267 			glCallList(fishList);
268                         *polys += fish_polys;
269 		}
270 		glPopMatrix();
271 	}
272 
273 	glFinish();
274 }
275