1 /*
2     OpenUniverse 1.0
3     Copyright (C) 2000  Raul Alonso <amil@las.es>
4 
5     This program is free software; you can redistribute it and/or modify
6     it under the terms of the GNU General Public License as published by
7     the Free Software Foundation; either version 2 of the License, or
8     (at your option) any later version.
9 
10     This program is distributed in the hope that it will be useful,
11     but WITHOUT ANY WARRANTY; without even the implied warranty of
12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13     GNU General Public License for more details.
14 
15     You should have received a copy of the GNU General Public License
16     along with this program; if not, write to the Free Software
17     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19 
20 #include "ou.h"
21 
22 static void Ring(double, double, int, planetdata *);
23 static int inrange(double, double, double);
24 
DrawRing(int body)25 void DrawRing(int body)
26 {
27 	glBindTexture(GL_TEXTURE_2D, planets[body].textures[0]);
28 	glDisable(GL_CULL_FACE);
29 	glDisable(GL_LIGHTING);
30 	glEnable(GL_BLEND);
31 	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
32 	Ring(RADIUSSCALE(planets[body].InnerRadius),
33 		 RADIUSSCALE(planets[body].Radius), slices * 2, &planets[body]);
34 	if (lighting)
35 		glEnable(GL_LIGHTING);
36 	glEnable(GL_CULL_FACE);
37 	glDisable(GL_BLEND);
38 }
39 
40 
Ring(double innerRadius,double outerRadius,int slices,planetdata * pdata)41 static void Ring(double innerRadius, double outerRadius, int slices,
42 				 planetdata * pdata)
43 {
44 	GLfloat da, dr;
45 	int j = pdata->Sat;
46 	GLfloat sa, ca;
47 	GLfloat r1 = innerRadius;
48 	GLfloat r2;
49 	GLint s;
50 	GLfloat a;
51 	double b;
52 
53 
54 	if (!pdata->initialized) {
55 		pdata->vertex_list =
56 			(vertex_data *) malloc(sizeof(vertex_data) * (slices + 1) * 2);
57 		pdata->indices =
58 			(GLuint *) malloc(sizeof(GLuint) * (slices + 1) * 2);
59 
60 		da = 2.0 * M_PI / slices;
61 		dr = (outerRadius - innerRadius);
62 		r2 = r1 + dr;
63 
64 		for (s = 0; s <= slices; s++) {
65 			if (s == slices)
66 				a = 0.0;
67 			else
68 				a = s * da;
69 			sa = sin(a);
70 			ca = cos(a);
71 			if (s % 2) {
72 				pdata->vertex_list[s * 2].u = 1.0;
73 				pdata->vertex_list[s * 2].v = 0.0;
74 			} else {
75 				pdata->vertex_list[s * 2].u = 1.0;
76 				pdata->vertex_list[s * 2].v = 1.0;
77 			}
78 
79 			pdata->vertex_list[s * 2].x = r2 * sa;
80 			pdata->vertex_list[s * 2].y = r2 * ca;
81 			pdata->vertex_list[s * 2].z = 0.0;
82 			pdata->vertex_list[s * 2].nx = 0.0;
83 			pdata->vertex_list[s * 2].ny = 0.0;
84 			pdata->vertex_list[s * 2].nz = 1.0;
85 			pdata->indices[s * 2] = s * 2;
86 
87 			if (a < (M_PI / 3.0)) {
88 				pdata->vertex_list[s * 2].r =
89 					pdata->vertex_list[s * 2].g =
90 					pdata->vertex_list[s * 2].b = 0.2;
91 				pdata->vertex_list[s * 2].a = 1.0;
92 			} else {
93 				pdata->vertex_list[s * 2].r = pdata->Color[0];
94 				pdata->vertex_list[s * 2].g = pdata->Color[1];
95 				pdata->vertex_list[s * 2].b = pdata->Color[2];
96 				pdata->vertex_list[s * 2].a = 1.0;
97 			}
98 
99 
100 			if (s % 2) {
101 				pdata->vertex_list[s * 2 + 1].u = 0.0;
102 				pdata->vertex_list[s * 2 + 1].v = 0.0;
103 			} else {
104 				pdata->vertex_list[s * 2 + 1].u = 0.0;
105 				pdata->vertex_list[s * 2 + 1].v = 1.0;
106 			}
107 
108 			pdata->vertex_list[s * 2 + 1].x = r1 * sa;
109 			pdata->vertex_list[s * 2 + 1].y = r1 * ca;
110 			pdata->vertex_list[s * 2 + 1].z = 0.0;
111 			pdata->vertex_list[s * 2 + 1].nx = 0.0;
112 			pdata->vertex_list[s * 2 + 1].ny = 0.0;
113 			pdata->vertex_list[s * 2 + 1].nz = 1.0;
114 			pdata->indices[s * 2 + 1] = s * 2 + 1;
115 
116 			if (a < (M_PI / 3.0)) {
117 				pdata->vertex_list[s * 2 + 1].r =
118 					pdata->vertex_list[s * 2 + 1].g =
119 					pdata->vertex_list[s * 2 + 1].b = 0.2;
120 				pdata->vertex_list[s * 2 + 1].a = 1.0;
121 			} else {
122 				pdata->vertex_list[s * 2 + 1].r = pdata->Color[0];
123 				pdata->vertex_list[s * 2 + 1].g = pdata->Color[1];
124 				pdata->vertex_list[s * 2 + 1].b = pdata->Color[2];
125 				pdata->vertex_list[s * 2 + 1].a = 1.0;
126 			}
127 		}
128 		pdata->initialized = 1;
129 	} else {
130 		da = 2.0 * M_PI / slices;
131 		dr = (outerRadius - innerRadius);
132 		r2 = r1 + dr;
133 		for (s = 0; s <= slices; s++) {
134 			if (s == slices)
135 				a = 0.0;
136 			else
137 				a = s * da;
138 			sa = sin(a);
139 			ca = cos(a);
140 			b =
141 				DEG2RAD(planets[j].DeltaRotation) +
142 				atan2(planets[j].pos[Z], planets[j].pos[X]) + M_PI / 3.0;
143 			while (b > (2 * M_PI))
144 				b -= (2 * M_PI);
145 			while (b < 0.0)
146 				b += (2 * M_PI);
147 			if (inrange(a, b, b + M_PI / 3.0)) {
148 
149 				pdata->vertex_list[s * 2].r =
150 					pdata->vertex_list[s * 2].g =
151 					pdata->vertex_list[s * 2].b = 0.2;
152 				pdata->vertex_list[s * 2].a = 1.0;
153 				pdata->vertex_list[s * 2 + 1].r =
154 					pdata->vertex_list[s * 2 + 1].g =
155 					pdata->vertex_list[s * 2 + 1].b = 0.2;
156 				pdata->vertex_list[s * 2 + 1].a = 1.0;
157 			} else {
158 				pdata->vertex_list[s * 2].r = pdata->Color[0];
159 				pdata->vertex_list[s * 2].g = pdata->Color[1];
160 				pdata->vertex_list[s * 2].b = pdata->Color[2];
161 				pdata->vertex_list[s * 2].a = 1.0;
162 				pdata->vertex_list[s * 2 + 1].r = pdata->Color[0];
163 				pdata->vertex_list[s * 2 + 1].g = pdata->Color[1];
164 				pdata->vertex_list[s * 2 + 1].b = pdata->Color[2];
165 				pdata->vertex_list[s * 2 + 1].a = 1.0;
166 			}
167 		}
168 		glInterleavedArrays(GL_T2F_C4F_N3F_V3F, 0, pdata->vertex_list);
169 		glDrawElements(GL_QUAD_STRIP, (slices + 1) * 2, GL_UNSIGNED_INT,
170 					   pdata->indices);
171 	}
172 }
173 
inrange(double a,double b,double c)174 static int inrange(double a, double b, double c)
175 {
176 	int i = 0;
177 	double tmp;
178 
179 	if (c > (2 * M_PI))
180 		tmp = a + 2 * M_PI;
181 	else
182 		tmp = a;
183 	if ((tmp >= b) && (tmp <= c))
184 		i = 1;
185 	if ((a >= b) && (a <= c))
186 		i = 1;
187 	return i;
188 }
189