llcylinder.cpp
上传用户:king477883
上传日期:2021-03-01
资源大小:9553k
文件大小:6k
源码类别:

游戏引擎

开发平台:

C++ Builder

  1. /** 
  2.  * @file llcylinder.cpp
  3.  * @brief Draws a cylinder using display lists for speed.
  4.  *
  5.  * $LicenseInfo:firstyear=2001&license=viewergpl$
  6.  * 
  7.  * Copyright (c) 2001-2010, Linden Research, Inc.
  8.  * 
  9.  * Second Life Viewer Source Code
  10.  * The source code in this file ("Source Code") is provided by Linden Lab
  11.  * to you under the terms of the GNU General Public License, version 2.0
  12.  * ("GPL"), unless you have obtained a separate licensing agreement
  13.  * ("Other License"), formally executed by you and Linden Lab.  Terms of
  14.  * the GPL can be found in doc/GPL-license.txt in this distribution, or
  15.  * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
  16.  * 
  17.  * There are special exceptions to the terms and conditions of the GPL as
  18.  * it is applied to this Source Code. View the full text of the exception
  19.  * in the file doc/FLOSS-exception.txt in this software distribution, or
  20.  * online at
  21.  * http://secondlifegrid.net/programs/open_source/licensing/flossexception
  22.  * 
  23.  * By copying, modifying or distributing this software, you acknowledge
  24.  * that you have read and understood your obligations described above,
  25.  * and agree to abide by those obligations.
  26.  * 
  27.  * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
  28.  * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
  29.  * COMPLETENESS OR PERFORMANCE.
  30.  * $/LicenseInfo$
  31.  */
  32. #include "llviewerprecompiledheaders.h"
  33. #include "llcylinder.h"
  34. #include "llerror.h"
  35. #include "math.h"
  36. #include "llmath.h"
  37. #include "noise.h"
  38. #include "v3math.h"
  39. #include "llvertexbuffer.h"
  40. #include "llgl.h"
  41. #include "llglheaders.h"
  42. LLCylinder gCylinder;
  43. LLCone gCone;
  44. GLUquadricObj* gQuadObj = NULL;
  45. static const GLint SLICES[] = { 30, 20, 12, 6 }; // same as sphere slices
  46. static const GLint STACKS = 2;
  47. static const GLfloat RADIUS = 0.5f;
  48. // draws a cylinder or cone
  49. // returns approximate number of triangles required
  50. U32 draw_cylinder_side(GLint slices, GLint stacks, GLfloat base_radius, GLfloat top_radius)
  51. {
  52. U32 triangles = 0;
  53. GLfloat height = 1.0f;
  54. if (!gQuadObj)
  55. {
  56. gQuadObj = gluNewQuadric();
  57. if (!gQuadObj) llerror("draw_cylindrical_body couldn't allocated quadric", 0);
  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. return triangles;
  66. }
  67. // Returns number of triangles required to draw
  68. // Need to know if top or not to set lighting normals
  69. const BOOL TOP = TRUE;
  70. const BOOL BOTTOM = FALSE;
  71. U32 draw_cylinder_cap(GLint slices, GLfloat base_radius, BOOL is_top)
  72. {
  73. U32 triangles = 0;
  74. if (!gQuadObj)
  75. {
  76. gQuadObj = gluNewQuadric();
  77. if (!gQuadObj) llerror("draw_cylinder_base couldn't allocated quadric", 0);
  78. }
  79. gluQuadricDrawStyle(gQuadObj, GLU_FILL);
  80. gluQuadricNormals(gQuadObj, GLU_SMOOTH);
  81. gluQuadricOrientation(gQuadObj, GLU_OUTSIDE);
  82. gluQuadricTexture(gQuadObj, GL_TRUE);
  83. // no hole in the middle of the disk, and just one ring
  84. GLdouble inner_radius = 0.0;
  85. GLint rings = 1;
  86. // normals point in +z for top, -z for base
  87. if (is_top)
  88. {
  89. gluQuadricOrientation(gQuadObj, GLU_OUTSIDE);
  90. }
  91. else
  92. {
  93. gluQuadricOrientation(gQuadObj, GLU_INSIDE);
  94. }
  95. gluDisk(gQuadObj, inner_radius, base_radius, slices, rings);
  96. triangles += slices;
  97. return triangles;
  98. }
  99. void LLCylinder::drawSide(S32 detail)
  100. {
  101. draw_cylinder_side(SLICES[detail], STACKS, RADIUS, RADIUS);
  102. }
  103. void LLCylinder::drawTop(S32 detail)
  104. {
  105. draw_cylinder_cap(SLICES[detail], RADIUS, TOP);
  106. }
  107. void LLCylinder::drawBottom(S32 detail)
  108. {
  109. draw_cylinder_cap(SLICES[detail], RADIUS, BOTTOM);
  110. }
  111. void LLCylinder::prerender()
  112. {
  113. }
  114. void LLCylinder::cleanupGL()
  115. {
  116. if (gQuadObj)
  117. {
  118. gluDeleteQuadric(gQuadObj);
  119. gQuadObj = NULL;
  120. }
  121. }
  122. void LLCylinder::render(F32 pixel_area)
  123. {
  124. renderface(pixel_area, 0);
  125. renderface(pixel_area, 1);
  126. renderface(pixel_area, 2);
  127. }
  128. void LLCylinder::renderface(F32 pixel_area, S32 face)
  129. {
  130. if (face < 0 || face > 2)
  131. {
  132. llerror("LLCylinder::renderface() invalid face number", face);
  133. return;
  134. }
  135. glMatrixMode(GL_MODELVIEW);
  136. glPushMatrix();
  137. S32 level_of_detail;
  138. if (pixel_area > 20000.f)
  139. {
  140. level_of_detail = 0;
  141. }
  142. else if (pixel_area > 1600.f)
  143. {
  144. level_of_detail = 1;
  145. }
  146. else if (pixel_area > 200.f)
  147. {
  148. level_of_detail = 2;
  149. }
  150. else
  151. {
  152. level_of_detail = 3;
  153. }
  154. if (level_of_detail < 0 || CYLINDER_LEVELS_OF_DETAIL <= level_of_detail)
  155. {
  156. llerror("LLCylinder::renderface() invalid level of detail", level_of_detail);
  157. return;
  158. }
  159. LLVertexBuffer::unbind();
  160. switch(face)
  161. {
  162. case 0:
  163. glTranslatef(0.f, 0.f, -0.5f);
  164. drawSide(level_of_detail);
  165. break;
  166. case 1:
  167. glTranslatef(0.0f, 0.f, 0.5f);
  168. drawTop(level_of_detail);
  169. break;
  170. case 2:
  171. glTranslatef(0.0f, 0.f, -0.5f);
  172. drawBottom(level_of_detail);
  173. break;
  174. default:
  175. llerror("LLCylinder::renderface() fell out of switch", 0);
  176. break;
  177. }
  178. glMatrixMode(GL_MODELVIEW);
  179. glPopMatrix();
  180. }
  181. //
  182. // Cones
  183. //
  184. void LLCone::prerender()
  185. {
  186. }
  187. void LLCone::cleanupGL()
  188. {
  189. if (gQuadObj)
  190. {
  191. gluDeleteQuadric(gQuadObj);
  192. gQuadObj = NULL;
  193. }
  194. }
  195. void LLCone::drawSide(S32 detail)
  196. {
  197. draw_cylinder_side( SLICES[detail], STACKS, RADIUS, 0.f );
  198. }
  199. void LLCone::drawBottom(S32 detail)
  200. {
  201. draw_cylinder_cap( SLICES[detail], RADIUS, BOTTOM );
  202. }
  203. void LLCone::render(S32 level_of_detail)
  204. {
  205. GLfloat height = 1.0f;
  206. if (level_of_detail < 0 || CONE_LEVELS_OF_DETAIL <= level_of_detail)
  207. {
  208. llerror("LLCone::render() invalid level of detail", level_of_detail);
  209. return;
  210. }
  211. glMatrixMode(GL_MODELVIEW);
  212. glPushMatrix();
  213. // center object at 0
  214. glTranslatef(0.f, 0.f, - height / 2.0f);
  215. drawSide(level_of_detail);
  216. drawBottom(level_of_detail);
  217. glMatrixMode(GL_MODELVIEW);
  218. glPopMatrix();
  219. }
  220. void LLCone::renderface(S32 level_of_detail, S32 face)
  221. {
  222. if (face < 0 || face > 1)
  223. {
  224. llerror("LLCone::renderface() invalid face number", face);
  225. return;
  226. }
  227. if (level_of_detail < 0 || CONE_LEVELS_OF_DETAIL <= level_of_detail)
  228. {
  229. llerror("LLCone::renderface() invalid level of detail", level_of_detail);
  230. return;
  231. }
  232. glMatrixMode(GL_MODELVIEW);
  233. glPushMatrix();
  234. LLVertexBuffer::unbind();
  235. switch(face)
  236. {
  237. case 0:
  238. glTranslatef(0.f, 0.f, -0.5f);
  239. drawSide(level_of_detail);
  240. break;
  241. case 1:
  242. glTranslatef(0.f, 0.f, -0.5f);
  243. drawBottom(level_of_detail);
  244. break;
  245. default:
  246. llerror("LLCylinder::renderface() fell out of switch", 0);
  247. break;
  248. }
  249. glMatrixMode(GL_MODELVIEW);
  250. glPopMatrix();
  251. }