llcylinder.cpp

Go to the documentation of this file.
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 };                // same as sphere slices
00051 static const GLint STACKS = 2;
00052 static const GLfloat RADIUS = 0.5f;
00053         
00054 // draws a cylinder or cone
00055 // returns approximate number of triangles required
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 // Returns number of triangles required to draw
00080 // Need to know if top or not to set lighting normals
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         // no hole in the middle of the disk, and just one ring
00099         GLdouble inner_radius = 0.0;
00100         GLint rings = 1;
00101 
00102         // normals point in +z for top, -z for base
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 // Cones
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         // center object at 0
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 }

Generated on Thu Jul 1 06:08:23 2010 for Second Life Viewer by  doxygen 1.4.7