aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/newview/llcylinder.cpp
diff options
context:
space:
mode:
authorJacek Antonelli2008-08-15 23:44:46 -0500
committerJacek Antonelli2008-08-15 23:44:46 -0500
commit38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4 (patch)
treeadca584755d22ca041a2dbfc35d4eca01f70b32c /linden/indra/newview/llcylinder.cpp
parentREADME.txt (diff)
downloadmeta-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.cpp327
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
41LLCylinder gCylinder;
42LLCone gCone;
43
44GLUquadricObj* gQuadObj = NULL;
45
46// draws a cylinder or cone
47// returns approximate number of triangles required
48U32 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
73const BOOL TOP = TRUE;
74const BOOL BOTTOM = FALSE;
75U32 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
110void 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
137void 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
156void LLCylinder::render(F32 pixel_area)
157{
158 renderface(pixel_area, 0);
159 renderface(pixel_area, 1);
160 renderface(pixel_area, 2);
161}
162
163
164void 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
228void 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
250void 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
269void 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
293void 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}