diff options
author | Jacek Antonelli | 2008-08-15 23:44:46 -0500 |
---|---|---|
committer | Jacek Antonelli | 2008-08-15 23:44:46 -0500 |
commit | 38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4 (patch) | |
tree | adca584755d22ca041a2dbfc35d4eca01f70b32c /linden/indra/newview/llcylinder.cpp | |
parent | README.txt (diff) | |
download | meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.zip meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.gz meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.bz2 meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.xz |
Second Life viewer sources 1.13.2.12
Diffstat (limited to 'linden/indra/newview/llcylinder.cpp')
-rw-r--r-- | linden/indra/newview/llcylinder.cpp | 327 |
1 files changed, 327 insertions, 0 deletions
diff --git a/linden/indra/newview/llcylinder.cpp b/linden/indra/newview/llcylinder.cpp new file mode 100644 index 0000000..b3eaa44 --- /dev/null +++ b/linden/indra/newview/llcylinder.cpp | |||
@@ -0,0 +1,327 @@ | |||
1 | /** | ||
2 | * @file llcylinder.cpp | ||
3 | * @brief Draws a cylinder using display lists for speed. | ||
4 | * | ||
5 | * Copyright (c) 2001-2007, Linden Research, Inc. | ||
6 | * | ||
7 | * The source code in this file ("Source Code") is provided by Linden Lab | ||
8 | * to you under the terms of the GNU General Public License, version 2.0 | ||
9 | * ("GPL"), unless you have obtained a separate licensing agreement | ||
10 | * ("Other License"), formally executed by you and Linden Lab. Terms of | ||
11 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | ||
12 | * online at http://secondlife.com/developers/opensource/gplv2 | ||
13 | * | ||
14 | * There are special exceptions to the terms and conditions of the GPL as | ||
15 | * it is applied to this Source Code. View the full text of the exception | ||
16 | * in the file doc/FLOSS-exception.txt in this software distribution, or | ||
17 | * online at http://secondlife.com/developers/opensource/flossexception | ||
18 | * | ||
19 | * By copying, modifying or distributing this software, you acknowledge | ||
20 | * that you have read and understood your obligations described above, | ||
21 | * and agree to abide by those obligations. | ||
22 | * | ||
23 | * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO | ||
24 | * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, | ||
25 | * COMPLETENESS OR PERFORMANCE. | ||
26 | */ | ||
27 | |||
28 | #include "llviewerprecompiledheaders.h" | ||
29 | |||
30 | #include "llcylinder.h" | ||
31 | |||
32 | #include "llerror.h" | ||
33 | #include "math.h" | ||
34 | #include "llmath.h" | ||
35 | #include "noise.h" | ||
36 | #include "v3math.h" | ||
37 | |||
38 | #include "llgl.h" | ||
39 | #include "llglheaders.h" | ||
40 | |||
41 | LLCylinder gCylinder; | ||
42 | LLCone gCone; | ||
43 | |||
44 | GLUquadricObj* gQuadObj = NULL; | ||
45 | |||
46 | // draws a cylinder or cone | ||
47 | // returns approximate number of triangles required | ||
48 | U32 draw_cylinder_side(GLint slices, GLint stacks, GLfloat base_radius, GLfloat top_radius) | ||
49 | { | ||
50 | U32 triangles = 0; | ||
51 | GLfloat height = 1.0f; | ||
52 | |||
53 | if (!gQuadObj) | ||
54 | { | ||
55 | gQuadObj = gluNewQuadric(); | ||
56 | if (!gQuadObj) llerror("draw_cylindrical_body couldn't allocated quadric", 0); | ||
57 | } | ||
58 | |||
59 | gluQuadricDrawStyle(gQuadObj, GLU_FILL); | ||
60 | gluQuadricNormals(gQuadObj, GLU_SMOOTH); | ||
61 | gluQuadricOrientation(gQuadObj, GLU_OUTSIDE); | ||
62 | gluQuadricTexture(gQuadObj, GL_TRUE); | ||
63 | gluCylinder(gQuadObj, base_radius, top_radius, height, slices, stacks); | ||
64 | triangles += stacks * (slices * 2); | ||
65 | |||
66 | |||
67 | return triangles; | ||
68 | } | ||
69 | |||
70 | |||
71 | // Returns number of triangles required to draw | ||
72 | // Need to know if top or not to set lighting normals | ||
73 | const BOOL TOP = TRUE; | ||
74 | const BOOL BOTTOM = FALSE; | ||
75 | U32 draw_cylinder_cap(GLint slices, GLfloat base_radius, BOOL is_top) | ||
76 | { | ||
77 | U32 triangles = 0; | ||
78 | |||
79 | if (!gQuadObj) | ||
80 | { | ||
81 | gQuadObj = gluNewQuadric(); | ||
82 | if (!gQuadObj) llerror("draw_cylinder_base couldn't allocated quadric", 0); | ||
83 | } | ||
84 | |||
85 | gluQuadricDrawStyle(gQuadObj, GLU_FILL); | ||
86 | gluQuadricNormals(gQuadObj, GLU_SMOOTH); | ||
87 | gluQuadricOrientation(gQuadObj, GLU_OUTSIDE); | ||
88 | gluQuadricTexture(gQuadObj, GL_TRUE); | ||
89 | |||
90 | // no hole in the middle of the disk, and just one ring | ||
91 | GLdouble inner_radius = 0.0; | ||
92 | GLint rings = 1; | ||
93 | |||
94 | // normals point in +z for top, -z for base | ||
95 | if (is_top) | ||
96 | { | ||
97 | gluQuadricOrientation(gQuadObj, GLU_OUTSIDE); | ||
98 | } | ||
99 | else | ||
100 | { | ||
101 | gluQuadricOrientation(gQuadObj, GLU_INSIDE); | ||
102 | } | ||
103 | gluDisk(gQuadObj, inner_radius, base_radius, slices, rings); | ||
104 | triangles += slices; | ||
105 | |||
106 | return triangles; | ||
107 | } | ||
108 | |||
109 | |||
110 | void LLCylinder::prerender() | ||
111 | { | ||
112 | GLint stacks = 2; | ||
113 | GLfloat radius = 0.5f; | ||
114 | GLint slices[CYLINDER_LEVELS_OF_DETAIL] = { 30, 20, 12, 6 }; // same as sphere slices | ||
115 | |||
116 | for (S32 detail = 0; detail < CYLINDER_LEVELS_OF_DETAIL; detail++) | ||
117 | { | ||
118 | mTriangleCount[detail] = 0; | ||
119 | |||
120 | mDisplayListSide[detail] = glGenLists(1); | ||
121 | glNewList(mDisplayListSide[detail], GL_COMPILE); | ||
122 | mTriangleCount[detail] += draw_cylinder_side( slices[detail], stacks, radius, radius ); | ||
123 | glEndList(); | ||
124 | |||
125 | mDisplayListTop[detail] = glGenLists(1); | ||
126 | glNewList( mDisplayListTop[detail], GL_COMPILE); | ||
127 | mTriangleCount[detail] += draw_cylinder_cap( slices[detail], radius, TOP ); | ||
128 | glEndList(); | ||
129 | |||
130 | mDisplayListBottom[detail] = glGenLists(1); | ||
131 | glNewList( mDisplayListBottom[detail], GL_COMPILE); | ||
132 | mTriangleCount[detail] += draw_cylinder_cap( slices[detail], radius, BOTTOM ); | ||
133 | glEndList(); | ||
134 | } | ||
135 | } | ||
136 | |||
137 | void LLCylinder::cleanupGL() | ||
138 | { | ||
139 | for (S32 detail = 0; detail < CYLINDER_LEVELS_OF_DETAIL; detail++) | ||
140 | { | ||
141 | glDeleteLists(mDisplayListSide[detail], 1); | ||
142 | mDisplayListSide[detail] = 0; | ||
143 | glDeleteLists(mDisplayListTop[detail], 1); | ||
144 | mDisplayListTop[detail] = 0; | ||
145 | glDeleteLists(mDisplayListBottom[detail], 1); | ||
146 | mDisplayListBottom[detail] = 0; | ||
147 | } | ||
148 | |||
149 | if (gQuadObj) | ||
150 | { | ||
151 | gluDeleteQuadric(gQuadObj); | ||
152 | gQuadObj = NULL; | ||
153 | } | ||
154 | } | ||
155 | |||
156 | void LLCylinder::render(F32 pixel_area) | ||
157 | { | ||
158 | renderface(pixel_area, 0); | ||
159 | renderface(pixel_area, 1); | ||
160 | renderface(pixel_area, 2); | ||
161 | } | ||
162 | |||
163 | |||
164 | void LLCylinder::renderface(F32 pixel_area, S32 face) | ||
165 | { | ||
166 | if (face < 0 || face > 2) | ||
167 | { | ||
168 | llerror("LLCylinder::renderface() invalid face number", face); | ||
169 | return; | ||
170 | } | ||
171 | |||
172 | glMatrixMode(GL_MODELVIEW); | ||
173 | glPushMatrix(); | ||
174 | |||
175 | S32 level_of_detail; | ||
176 | |||
177 | if (pixel_area > 20000.f) | ||
178 | { | ||
179 | level_of_detail = 0; | ||
180 | } | ||
181 | else if (pixel_area > 1600.f) | ||
182 | { | ||
183 | level_of_detail = 1; | ||
184 | } | ||
185 | else if (pixel_area > 200.f) | ||
186 | { | ||
187 | level_of_detail = 2; | ||
188 | } | ||
189 | else | ||
190 | { | ||
191 | level_of_detail = 3; | ||
192 | } | ||
193 | |||
194 | if (level_of_detail < 0 || CYLINDER_LEVELS_OF_DETAIL <= level_of_detail) | ||
195 | { | ||
196 | llerror("LLCylinder::renderface() invalid level of detail", level_of_detail); | ||
197 | return; | ||
198 | } | ||
199 | |||
200 | switch(face) | ||
201 | { | ||
202 | case 0: | ||
203 | glTranslatef(0.f, 0.f, -0.5f); | ||
204 | glCallList(mDisplayListSide[level_of_detail]); | ||
205 | break; | ||
206 | case 1: | ||
207 | glTranslatef(0.0f, 0.f, 0.5f); | ||
208 | glCallList(mDisplayListTop[level_of_detail]); | ||
209 | break; | ||
210 | case 2: | ||
211 | glTranslatef(0.0f, 0.f, -0.5f); | ||
212 | glCallList(mDisplayListBottom[level_of_detail]); | ||
213 | break; | ||
214 | default: | ||
215 | llerror("LLCylinder::renderface() fell out of switch", 0); | ||
216 | break; | ||
217 | } | ||
218 | |||
219 | glMatrixMode(GL_MODELVIEW); | ||
220 | glPopMatrix(); | ||
221 | } | ||
222 | |||
223 | |||
224 | // | ||
225 | // Cones | ||
226 | // | ||
227 | |||
228 | void LLCone::prerender() | ||
229 | { | ||
230 | GLint stacks = 2; | ||
231 | GLfloat radius = 0.5f; | ||
232 | GLint slices[CONE_LEVELS_OF_DETAIL] = { 32, 18, 12, 6 }; | ||
233 | |||
234 | for (S32 detail = 0; detail < CONE_LEVELS_OF_DETAIL; detail++) | ||
235 | { | ||
236 | mTriangleCount[detail] = 0; | ||
237 | |||
238 | mDisplayListSide[detail] = glGenLists(1); | ||
239 | glNewList(mDisplayListSide[detail], GL_COMPILE); | ||
240 | mTriangleCount[detail] += draw_cylinder_side( slices[detail], stacks, radius, 0.f ); | ||
241 | glEndList(); | ||
242 | |||
243 | mDisplayListBottom[detail] = glGenLists(1); | ||
244 | glNewList( mDisplayListBottom[detail], GL_COMPILE); | ||
245 | mTriangleCount[detail] += draw_cylinder_cap( slices[detail], radius, BOTTOM ); | ||
246 | glEndList(); | ||
247 | } | ||
248 | } | ||
249 | |||
250 | void LLCone::cleanupGL() | ||
251 | { | ||
252 | for (S32 detail = 0; detail < CYLINDER_LEVELS_OF_DETAIL; detail++) | ||
253 | { | ||
254 | glDeleteLists(mDisplayListSide[detail], 1); | ||
255 | mDisplayListSide[detail] = 0; | ||
256 | |||
257 | glDeleteLists(mDisplayListBottom[detail], 1); | ||
258 | mDisplayListBottom[detail] = 0; | ||
259 | } | ||
260 | |||
261 | if (gQuadObj) | ||
262 | { | ||
263 | gluDeleteQuadric(gQuadObj); | ||
264 | gQuadObj = NULL; | ||
265 | } | ||
266 | } | ||
267 | |||
268 | |||
269 | void LLCone::render(S32 level_of_detail) | ||
270 | { | ||
271 | GLfloat height = 1.0f; | ||
272 | |||
273 | if (level_of_detail < 0 || CONE_LEVELS_OF_DETAIL <= level_of_detail) | ||
274 | { | ||
275 | llerror("LLCone::render() invalid level of detail", level_of_detail); | ||
276 | return; | ||
277 | } | ||
278 | |||
279 | glMatrixMode(GL_MODELVIEW); | ||
280 | glPushMatrix(); | ||
281 | |||
282 | // center object at 0 | ||
283 | glTranslatef(0.f, 0.f, - height / 2.0f); | ||
284 | |||
285 | glCallList(mDisplayListSide[level_of_detail]); | ||
286 | glCallList(mDisplayListBottom[level_of_detail]); | ||
287 | |||
288 | glMatrixMode(GL_MODELVIEW); | ||
289 | glPopMatrix(); | ||
290 | } | ||
291 | |||
292 | |||
293 | void LLCone::renderface(S32 level_of_detail, S32 face) | ||
294 | { | ||
295 | if (face < 0 || face > 1) | ||
296 | { | ||
297 | llerror("LLCone::renderface() invalid face number", face); | ||
298 | return; | ||
299 | } | ||
300 | |||
301 | if (level_of_detail < 0 || CONE_LEVELS_OF_DETAIL <= level_of_detail) | ||
302 | { | ||
303 | llerror("LLCone::renderface() invalid level of detail", level_of_detail); | ||
304 | return; | ||
305 | } | ||
306 | |||
307 | glMatrixMode(GL_MODELVIEW); | ||
308 | glPushMatrix(); | ||
309 | |||
310 | switch(face) | ||
311 | { | ||
312 | case 0: | ||
313 | glTranslatef(0.f, 0.f, -0.5f); | ||
314 | glCallList(mDisplayListSide[level_of_detail]); | ||
315 | break; | ||
316 | case 1: | ||
317 | glTranslatef(0.f, 0.f, -0.5f); | ||
318 | glCallList(mDisplayListBottom[level_of_detail]); | ||
319 | break; | ||
320 | default: | ||
321 | llerror("LLCylinder::renderface() fell out of switch", 0); | ||
322 | break; | ||
323 | } | ||
324 | |||
325 | glMatrixMode(GL_MODELVIEW); | ||
326 | glPopMatrix(); | ||
327 | } | ||