00001
00032 #include "llviewerprecompiledheaders.h"
00033
00034 #include "llcylinder.h"
00035
00036 #include "llerror.h"
00037 #include "math.h"
00038 #include "llmath.h"
00039 #include "noise.h"
00040 #include "v3math.h"
00041 #include "llvertexbuffer.h"
00042 #include "llgl.h"
00043 #include "llglheaders.h"
00044
00045 LLCylinder gCylinder;
00046 LLCone gCone;
00047
00048 GLUquadricObj* gQuadObj = NULL;
00049
00050 static const GLint SLICES[] = { 30, 20, 12, 6 };
00051 static const GLint STACKS = 2;
00052 static const GLfloat RADIUS = 0.5f;
00053
00054
00055
00056 U32 draw_cylinder_side(GLint slices, GLint stacks, GLfloat base_radius, GLfloat top_radius)
00057 {
00058 U32 triangles = 0;
00059 GLfloat height = 1.0f;
00060
00061 if (!gQuadObj)
00062 {
00063 gQuadObj = gluNewQuadric();
00064 if (!gQuadObj) llerror("draw_cylindrical_body couldn't allocated quadric", 0);
00065 }
00066
00067 gluQuadricDrawStyle(gQuadObj, GLU_FILL);
00068 gluQuadricNormals(gQuadObj, GLU_SMOOTH);
00069 gluQuadricOrientation(gQuadObj, GLU_OUTSIDE);
00070 gluQuadricTexture(gQuadObj, GL_TRUE);
00071 gluCylinder(gQuadObj, base_radius, top_radius, height, slices, stacks);
00072 triangles += stacks * (slices * 2);
00073
00074
00075 return triangles;
00076 }
00077
00078
00079
00080
00081 const BOOL TOP = TRUE;
00082 const BOOL BOTTOM = FALSE;
00083 U32 draw_cylinder_cap(GLint slices, GLfloat base_radius, BOOL is_top)
00084 {
00085 U32 triangles = 0;
00086
00087 if (!gQuadObj)
00088 {
00089 gQuadObj = gluNewQuadric();
00090 if (!gQuadObj) llerror("draw_cylinder_base couldn't allocated quadric", 0);
00091 }
00092
00093 gluQuadricDrawStyle(gQuadObj, GLU_FILL);
00094 gluQuadricNormals(gQuadObj, GLU_SMOOTH);
00095 gluQuadricOrientation(gQuadObj, GLU_OUTSIDE);
00096 gluQuadricTexture(gQuadObj, GL_TRUE);
00097
00098
00099 GLdouble inner_radius = 0.0;
00100 GLint rings = 1;
00101
00102
00103 if (is_top)
00104 {
00105 gluQuadricOrientation(gQuadObj, GLU_OUTSIDE);
00106 }
00107 else
00108 {
00109 gluQuadricOrientation(gQuadObj, GLU_INSIDE);
00110 }
00111 gluDisk(gQuadObj, inner_radius, base_radius, slices, rings);
00112 triangles += slices;
00113
00114 return triangles;
00115 }
00116
00117 void LLCylinder::drawSide(S32 detail)
00118 {
00119 draw_cylinder_side(SLICES[detail], STACKS, RADIUS, RADIUS);
00120 }
00121
00122 void LLCylinder::drawTop(S32 detail)
00123 {
00124 draw_cylinder_cap(SLICES[detail], RADIUS, TOP);
00125 }
00126
00127 void LLCylinder::drawBottom(S32 detail)
00128 {
00129 draw_cylinder_cap(SLICES[detail], RADIUS, BOTTOM);
00130 }
00131
00132 void LLCylinder::prerender()
00133 {
00134 }
00135
00136 void LLCylinder::cleanupGL()
00137 {
00138 if (gQuadObj)
00139 {
00140 gluDeleteQuadric(gQuadObj);
00141 gQuadObj = NULL;
00142 }
00143 }
00144
00145 void LLCylinder::render(F32 pixel_area)
00146 {
00147 renderface(pixel_area, 0);
00148 renderface(pixel_area, 1);
00149 renderface(pixel_area, 2);
00150 }
00151
00152
00153 void LLCylinder::renderface(F32 pixel_area, S32 face)
00154 {
00155 if (face < 0 || face > 2)
00156 {
00157 llerror("LLCylinder::renderface() invalid face number", face);
00158 return;
00159 }
00160
00161 glMatrixMode(GL_MODELVIEW);
00162 glPushMatrix();
00163
00164 S32 level_of_detail;
00165
00166 if (pixel_area > 20000.f)
00167 {
00168 level_of_detail = 0;
00169 }
00170 else if (pixel_area > 1600.f)
00171 {
00172 level_of_detail = 1;
00173 }
00174 else if (pixel_area > 200.f)
00175 {
00176 level_of_detail = 2;
00177 }
00178 else
00179 {
00180 level_of_detail = 3;
00181 }
00182
00183 if (level_of_detail < 0 || CYLINDER_LEVELS_OF_DETAIL <= level_of_detail)
00184 {
00185 llerror("LLCylinder::renderface() invalid level of detail", level_of_detail);
00186 return;
00187 }
00188
00189 LLVertexBuffer::unbind();
00190
00191 switch(face)
00192 {
00193 case 0:
00194 glTranslatef(0.f, 0.f, -0.5f);
00195 drawSide(level_of_detail);
00196 break;
00197 case 1:
00198 glTranslatef(0.0f, 0.f, 0.5f);
00199 drawTop(level_of_detail);
00200 break;
00201 case 2:
00202 glTranslatef(0.0f, 0.f, -0.5f);
00203 drawBottom(level_of_detail);
00204 break;
00205 default:
00206 llerror("LLCylinder::renderface() fell out of switch", 0);
00207 break;
00208 }
00209
00210 glMatrixMode(GL_MODELVIEW);
00211 glPopMatrix();
00212 }
00213
00214
00215
00216
00217
00218
00219 void LLCone::prerender()
00220 {
00221 }
00222
00223 void LLCone::cleanupGL()
00224 {
00225 if (gQuadObj)
00226 {
00227 gluDeleteQuadric(gQuadObj);
00228 gQuadObj = NULL;
00229 }
00230 }
00231
00232 void LLCone::drawSide(S32 detail)
00233 {
00234 draw_cylinder_side( SLICES[detail], STACKS, RADIUS, 0.f );
00235 }
00236
00237 void LLCone::drawBottom(S32 detail)
00238 {
00239 draw_cylinder_cap( SLICES[detail], RADIUS, BOTTOM );
00240 }
00241
00242 void LLCone::render(S32 level_of_detail)
00243 {
00244 GLfloat height = 1.0f;
00245
00246 if (level_of_detail < 0 || CONE_LEVELS_OF_DETAIL <= level_of_detail)
00247 {
00248 llerror("LLCone::render() invalid level of detail", level_of_detail);
00249 return;
00250 }
00251
00252 glMatrixMode(GL_MODELVIEW);
00253 glPushMatrix();
00254
00255
00256 glTranslatef(0.f, 0.f, - height / 2.0f);
00257
00258 LLVertexBuffer::unbind();
00259 drawSide(level_of_detail);
00260 drawBottom(level_of_detail);
00261
00262 glMatrixMode(GL_MODELVIEW);
00263 glPopMatrix();
00264 }
00265
00266
00267 void LLCone::renderface(S32 level_of_detail, S32 face)
00268 {
00269 if (face < 0 || face > 1)
00270 {
00271 llerror("LLCone::renderface() invalid face number", face);
00272 return;
00273 }
00274
00275 if (level_of_detail < 0 || CONE_LEVELS_OF_DETAIL <= level_of_detail)
00276 {
00277 llerror("LLCone::renderface() invalid level of detail", level_of_detail);
00278 return;
00279 }
00280
00281 glMatrixMode(GL_MODELVIEW);
00282 glPushMatrix();
00283
00284 LLVertexBuffer::unbind();
00285
00286 switch(face)
00287 {
00288 case 0:
00289 glTranslatef(0.f, 0.f, -0.5f);
00290 drawSide(level_of_detail);
00291 break;
00292 case 1:
00293 glTranslatef(0.f, 0.f, -0.5f);
00294 drawBottom(level_of_detail);
00295 break;
00296 default:
00297 llerror("LLCylinder::renderface() fell out of switch", 0);
00298 break;
00299 }
00300
00301 glMatrixMode(GL_MODELVIEW);
00302 glPopMatrix();
00303 }