Author Topic: GL Sphere  (Read 4498 times)

0 Members and 1 Guest are viewing this topic.

Offline Craz1000

  • Forum Regular
  • Posts: 111
  • I'm OK
    • View Profile
    • Craz1000.net
GL Sphere
« on: March 07, 2019, 07:57:50 pm »
anyone got a snippet of code lying around that will render a sphere at an x-z coordinate with a r radius?


I am trying to draw a sphere r size at Cam.PosX, Cam.PosY, Cam.PosZ. i found this online but it is not working well.

Code: QB64: [Select]
  1.         dTh = _PI / 9
  2.         dPh = _PI / 9
  3.         r = 20
  4.         _glBegin _GL_QUAD_STRIP
  5.         DO
  6.             DO
  7.                 z1 = Cam.PosZ + (r * SIN(ph + dPh) * COS(th + dTh))
  8.                 x1 = Cam.PosX + (r * SIN(ph + dPh) * SIN(th + dTh))
  9.                 y1 = Cam.PosY + (r * COS(ph + dPh))
  10.  
  11.                 z2 = Cam.PosZ + (r * SIN(ph) * COS(th + dTh))
  12.                 x2 = Cam.PosX + (r * SIN(ph) * SIN(th + dTh))
  13.                 y2 = Cam.PosY + (r * COS(ph))
  14.  
  15.                 z3 = Cam.PosZ + (r * SIN(ph) * COS(th))
  16.                 x3 = Cam.PosX + (r * SIN(ph) * SIN(th))
  17.                 y3 = Cam.PosY + (r * COS(ph))
  18.  
  19.                 z4 = Cam.PosZ + (r * SIN(ph + dPh) * COS(th))
  20.                 x4 = Cam.PosX + (r * SIN(ph + dPh) * SIN(th))
  21.                 y4 = Cam.PosY + (r * COS(ph + dPh))
  22.  
  23.                 _glColor3f 1, 0, 0
  24.                 _glVertex3f x4, y4, z4
  25.                 _glColor3f 1, 0, 0
  26.                 _glVertex3f x1, y1, z1
  27.                 _glColor3f 1, 0, 0
  28.                 _glVertex3f x2, y2, z2
  29.                 _glColor3f 1, 0, 0
  30.                 _glVertex3f x3, y3, z3
  31.  
  32.                 ph = ph + dPh
  33.             LOOP WHILE ph <= _PI
  34.             th = th + dTh
  35.         LOOP WHILE th <= 2 * _PI
  36.         _glEnd
  37.  
« Last Edit: March 08, 2019, 12:11:19 am by Craz1000 »

Offline Ashish

  • Forum Resident
  • Posts: 630
  • Never Give Up!
    • View Profile
Re: GL Sphere
« Reply #1 on: March 08, 2019, 08:18:15 am »
Hi! You can use glutSolidSphere() to draw a sphere of radius r and then you use glTranslatef() to place it anywhere in x-z plane.
Here's a quick demo -

Controls - Use 'w' & 's' for movement
Code: QB64: [Select]
  1. '##########################
  2. '  OpenGL 3D Shapes
  3. '    By Ashish Kushwaha
  4. '##########################
  5. ' :)
  6.  
  7. _TITLE "OpenGL 3D Shapes"
  8. SCREEN _NEWIMAGE(600, 600, 32)
  9.  
  10.  
  11. 'Sphere
  12.     SUB glutSolidSphere (BYVAL radius AS DOUBLE, BYVAL slices AS LONG, BYVAL stack AS LONG)
  13.     SUB glutWireSphere (BYVAL radius AS DOUBLE, BYVAL slices AS LONG, BYVAL stack AS LONG)
  14.  
  15.     'Cube
  16.     SUB glutWireCube (BYVAL dsize AS DOUBLE)
  17.     SUB glutSolidCube (BYVAL dsize AS DOUBLE)
  18.  
  19.     'Torus
  20.     SUB glutWireTorus (BYVAL dInnerRadius AS DOUBLE, BYVAL dOuterRadius AS DOUBLE, BYVAL nSides AS LONG, BYVAL nRings AS LONG)
  21.     SUB glutSolidTorus (BYVAL dInnerRadius AS DOUBLE, BYVAL dOuterRadius AS DOUBLE, BYVAL nSides AS LONG, BYVAL nRings AS LONG)
  22.  
  23.     'Cone
  24.     SUB glutWireCone (BYVAL base AS DOUBLE, BYVAL height AS DOUBLE, BYVAL slices AS LONG, BYVAL stack AS LONG)
  25.     SUB glutSolidCone (BYVAL base AS DOUBLE, BYVAL height AS DOUBLE, BYVAL slices AS LONG, BYVAL stack AS LONG)
  26.  
  27.     'Cylinder
  28.     SUB glutWireCylinder (BYVAL base AS DOUBLE, BYVAL height AS DOUBLE, BYVAL slices AS LONG, BYVAL stack AS LONG)
  29.     SUB glutSolidCylinder (BYVAL base AS DOUBLE, BYVAL height AS DOUBLE, BYVAL slices AS LONG, BYVAL stack AS LONG)
  30.  
  31.  
  32. 'Used by GLH RGB/etc helper functions
  33. DIM SHARED DONT_USE_GLH_COL_RGBA(1 TO 4) AS SINGLE
  34.  
  35. DIM SHARED shapeId
  36. DIM SHARED walk 'this will hold value about how close we are to our object
  37. walk = 5
  38.     k& = _KEYHIT
  39.     IF k& = ASC(" ") THEN
  40.         IF shapeId = 4 THEN shapeId = 0 ELSE shapeId = shapeId + 1
  41.     END IF
  42.     'Hi Sir!
  43.     'try to press 'w' or 's'
  44.     IF k& = ASC("s") THEN walk = walk + .05
  45.     IF k& = ASC("w") THEN walk = walk - .05
  46.     _LIMIT 30
  47.  
  48.  
  49.     'Enable Z-Buffer read/write
  50.     _glEnable _GL_DEPTH_TEST
  51.    
  52.     _glEnable _GL_LIGHTING
  53.     _glEnable _GL_LIGHT0
  54.    
  55.     _glLightfv _GL_LIGHT0, _GL_AMBIENT, GLH_RGB(.15, .15, .15)
  56.     _glLightfv _GL_LIGHT0, _GL_SPECULAR, GLH_RGB(.8, .8, .8)
  57.     _glLightfv _GL_LIGHT0, _GL_POSITION, GLH_RGBA(COS(clock#), 0, SIN(clock#), 0)
  58.    
  59.     'clears the depth
  60.     _glClearDepth 1.0
  61.    
  62.     'swich Projection matrix mode
  63.     _glMatrixMode _GL_PROJECTION
  64.    
  65.     'setting up perpective
  66.     aspect# = _WIDTH / _HEIGHT
  67.     _gluPerspective 40, aspect#, 1, 200
  68.    
  69.     'Now, we'll use ModelView
  70.     _glMatrixMode _GL_MODELVIEW
  71.    
  72.     _glClear _GL_COLOR_BUFFER_BIT OR _GL_DEPTH_BUFFER_BIT
  73.     'this clock# variable increases everytime as it is  used for rotation.
  74.     clock# = clock# + .01
  75.    
  76.     'note that  here walk value should be negative.
  77.     'Lesser the walk, object become closes, and vise versa
  78.     _glTranslatef 0, 0, -walk
  79.    
  80.     _glRotatef 30 * clock#, 1, 0, 0
  81.     _glRotatef 60 * clock#, 0, 1, 0
  82.     _glRotatef 90 * clock#, 0, 0, 1
  83.  
  84.     _glColor3f 1, 1, 1
  85.  
  86.     SELECT CASE shapeId
  87.         CASE 0
  88.             glutSolidSphere .5, 50, 50
  89.         CASE 1
  90.             glutSolidTorus .2, .5, 50, 50
  91.         CASE 2
  92.             glutSolidCube .5
  93.         CASE 3
  94.             glutSolidCone .4, .5, 30, 30
  95.         CASE 4
  96.             glutSolidCylinder .2, .8, 40, 40
  97.     END SELECT
  98.  
  99.     _glFlush
  100.  
  101. 'used opengl rgba functions
  102. FUNCTION GLH_RGB%& (r AS SINGLE, g AS SINGLE, b AS SINGLE)
  103.     DONT_USE_GLH_COL_RGBA(1) = r
  104.     DONT_USE_GLH_COL_RGBA(2) = g
  105.     DONT_USE_GLH_COL_RGBA(3) = b
  106.     DONT_USE_GLH_COL_RGBA(4) = 1
  107.     GLH_RGB = _OFFSET(DONT_USE_GLH_COL_RGBA())
  108.  
  109. FUNCTION GLH_RGBA%& (r AS SINGLE, g AS SINGLE, b AS SINGLE, a AS SINGLE)
  110.     DONT_USE_GLH_COL_RGBA(1) = r
  111.     DONT_USE_GLH_COL_RGBA(2) = g
  112.     DONT_USE_GLH_COL_RGBA(3) = b
  113.     DONT_USE_GLH_COL_RGBA(4) = a
  114.     GLH_RGBA = _OFFSET(DONT_USE_GLH_COL_RGBA())
  115.  
  116.  
if (Me.success) {Me.improve()} else {Me.tryAgain()}


My Projects - https://github.com/AshishKingdom?tab=repositories
OpenGL tutorials - https://ashishkingdom.github.io/OpenGL-Tutorials

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: GL Sphere
« Reply #2 on: March 08, 2019, 08:35:56 am »
Another awesome GL demo Ashish!

Offline Craz1000

  • Forum Regular
  • Posts: 111
  • I'm OK
    • View Profile
    • Craz1000.net
Re: GL Sphere
« Reply #3 on: March 08, 2019, 10:52:41 am »
Thanks Ashish not sure if i am explaining this properly. i am fairly new to GL

issue is i have already used translatef when it comes time for me to draw the sphere. Translate is set to the position of the camera then i draw the terrain and water. if i use translatef again it seems to be based on the camera set as the origin instead of the actual coordinates. for example if i translate -100 on Z it always puts the sphere in front of the camera, instead of -100 on z axis of the terrain.

here is my _GL

Code: QB64: [Select]
  1.     IF AllowSubGL = 0 THEN EXIT SUB
  2.  
  3.  
  4.     Land.AnimateClock = Land.AnimateClock + 1
  5.     IF Land.AnimateClock = 100 THEN Land.AnimateClock = 0
  6.  
  7.     IF Land.AnimateClock = 1 THEN Land.WaterTextureAnimate = 1
  8.     IF Land.AnimateClock = 25 THEN Land.WaterTextureAnimate = 2
  9.     IF Land.AnimateClock = 50 THEN Land.WaterTextureAnimate = 3
  10.     IF Land.AnimateClock = 75 THEN Land.WaterTextureAnimate = 4
  11.  
  12.     IF TexturesLoaded = 0 THEN
  13.         Grass1.Texture = GLH_Image_to_Texture(Grass1.Image)
  14.         Grass2.Texture = GLH_Image_to_Texture(Grass2.Image)
  15.         Grass3.Texture = GLH_Image_to_Texture(Grass3.Image)
  16.         Grass4.Texture = GLH_Image_to_Texture(Grass4.Image)
  17.         Water.Texture = GLH_Image_to_Texture(Water.Image)
  18.         _FREEIMAGE Grass1.Image
  19.         _FREEIMAGE Grass2.Image
  20.         _FREEIMAGE Grass3.Image
  21.         _FREEIMAGE Grass4.Image
  22.         _FREEIMAGE Water.Image
  23.         TexturesLoaded = 1
  24.     END IF
  25.  
  26.     _glMatrixMode _GL_PROJECTION
  27.     _gluPerspective 50, _WIDTH(0) / _HEIGHT(0), 1, 500
  28.     _glEnable _GL_TEXTURE_2D
  29.     _glEnable _GL_BLEND
  30.     _glEnable _GL_DEPTH_TEST
  31.     _glBlendFunc _GL_SRC_ALPHA, _GL_ONE_MINUS_SRC_ALPHA
  32.     _glEnable _GL_DEPTH_TEST
  33.     _glDepthMask _GL_TRUE
  34.     _glAlphaFunc _GL_GREATER, 0.5
  35.     _glEnable _GL_ALPHA_TEST
  36.     _glTexParameteri _GL_TEXTURE_2D, _GL_TEXTURE_MAG_FILTER, _GL_LINEAR
  37.     _glTexParameteri _GL_TEXTURE_2D, _GL_TEXTURE_MIN_FILTER, _GL_LINEAR
  38.  
  39.  
  40.     GLH_Select_Texture Grass2.Texture
  41.  
  42.  
  43.     '_glLoadIdentity
  44.     _glMatrixMode _GL_MODELVIEW
  45.     _glRotatef Cam.RotY, 0, 1, 0
  46.     _glRotatef Cam.RotX, 1, 0, 0
  47.     _glRotatef Cam.RotZ, 0, 0, 1
  48.     _glTranslatef Cam.PosX, Cam.PosY, Cam.PosZ
  49.  
  50.     _glTexParameteri _GL_TEXTURE_2D, _GL_TEXTURE_MIN_FILTER, _GL_LINEAR
  51.     _glTexParameteri _GL_TEXTURE_2D, _GL_TEXTURE_MAG_FILTER, _GL_LINEAR
  52.  
  53.  
  54.     FOR z = 0 TO Land.Blocks - 1  'Draws Terrain
  55.         FOR x = 0 TO Land.Blocks - 1
  56.             _glBegin _GL_QUADS
  57.             _glTexCoord2f 0, 0: _glVertex3f Land.BlockSize * x, Heightmap(x + 1, z + 2), Land.BlockSize * (z + 1)
  58.             _glTexCoord2f 1, 0: _glVertex3f Land.BlockSize * (x + 1), Heightmap(x + 2, z + 2), Land.BlockSize * (z + 1)
  59.             _glTexCoord2f 1, 1: _glVertex3f Land.BlockSize * (x + 1), Heightmap(x + 2, z + 1), Land.BlockSize * z
  60.             _glTexCoord2f 0, 1: _glVertex3f Land.BlockSize * x, Heightmap(x + 1, z + 1), Land.BlockSize * z
  61.             _glEnd
  62.         NEXT x
  63.     NEXT z
  64.  
  65.     GLH_Select_Texture Water.Texture
  66.  
  67.     IF Land.EnableWater = 1 THEN 'Draws Water
  68.         FOR x = 0 TO Land.BlockSize * Land.Blocks STEP Land.BlockSize * 10
  69.             FOR z = 0 TO Land.BlockSize * Land.Blocks STEP Land.BlockSize * 10
  70.                 _glBegin _GL_QUADS
  71.                 IF Land.WaterTextureAnimate = 1 THEN
  72.                     _glTexCoord2f 0, 0: _glVertex3f x, Land.WaterHeight, z
  73.                     _glTexCoord2f 1, 0: _glVertex3f x + (Land.BlockSize * 10), Land.WaterHeight, z
  74.                     _glTexCoord2f 1, 1: _glVertex3f x + (Land.BlockSize * 10), Land.WaterHeight, z + (Land.BlockSize * 10)
  75.                     _glTexCoord2f 0, 1: _glVertex3f x, Land.WaterHeight, z + (Land.BlockSize * 10)
  76.                 ELSEIF Land.WaterTextureAnimate = 2 THEN
  77.                     _glTexCoord2f 0, 1: _glVertex3f x, Land.WaterHeight, z
  78.                     _glTexCoord2f 0, 0: _glVertex3f x + (Land.BlockSize * 10), Land.WaterHeight, z
  79.                     _glTexCoord2f 1, 0: _glVertex3f x + (Land.BlockSize * 10), Land.WaterHeight, z + (Land.BlockSize * 10)
  80.                     _glTexCoord2f 1, 1: _glVertex3f x, Land.WaterHeight, z + (Land.BlockSize * 10)
  81.                 ELSEIF Land.WaterTextureAnimate = 3 THEN
  82.                     _glTexCoord2f 1, 1: _glVertex3f x, Land.WaterHeight, z
  83.                     _glTexCoord2f 0, 1: _glVertex3f x + (Land.BlockSize * 10), Land.WaterHeight, z
  84.                     _glTexCoord2f 0, 0: _glVertex3f x + (Land.BlockSize * 10), Land.WaterHeight, z + (Land.BlockSize * 10)
  85.                     _glTexCoord2f 1, 0: _glVertex3f x, Land.WaterHeight, z + (Land.BlockSize * 10)
  86.                 ELSEIF Land.WaterTextureAnimate = 4 THEN
  87.                     _glTexCoord2f 1, 0: _glVertex3f x, Land.WaterHeight, z
  88.                     _glTexCoord2f 1, 1: _glVertex3f x + (Land.BlockSize * 10), Land.WaterHeight, z
  89.                     _glTexCoord2f 0, 1: _glVertex3f x + (Land.BlockSize * 10), Land.WaterHeight, z + (Land.BlockSize * 10)
  90.                     _glTexCoord2f 0, 0: _glVertex3f x, Land.WaterHeight, z + (Land.BlockSize * 10)
  91.                 END IF
  92.                 _glEnd
  93.  
  94.             NEXT z
  95.         NEXT x
  96.     END IF
  97.  
  98.  
  99.     IF Fire.Active > 0 THEN  '************ here is where i am trying to draw a sphere at a specific coordinate on the terrain.
  100.         IF Fire.Active = 1 THEN
  101.             Fire.Animate = Fire.Animate + 1
  102.         ELSE
  103.             Fire.Animate = Fire.Animate - 1
  104.         END IF
  105.         _glMatrixMode _GL_MODELVIEW
  106.         _glPushMatrix
  107.         '_glTranslatef ABS(Cam.PosX), 0, ABS(Cam.PosZ)
  108.         _glTranslatef -100, GetHeight!(-100, -100), -100
  109.         glutSolidSphere Fire.Animate, 50, 50
  110.         _glPopMatrix
  111.  
  112.  
  113.         IF Fire.Animate = Fire.Radius THEN Fire.Active = 2
  114.         IF Fire.Animate = 0 THEN Fire.Active = 0
  115.     END IF
  116.  
« Last Edit: March 08, 2019, 11:04:41 am by Craz1000 »

Offline Ashish

  • Forum Resident
  • Posts: 630
  • Never Give Up!
    • View Profile
Re: GL Sphere
« Reply #4 on: March 08, 2019, 11:07:17 am »
Can you please provide the full code along with essential files?
if (Me.success) {Me.improve()} else {Me.tryAgain()}


My Projects - https://github.com/AshishKingdom?tab=repositories
OpenGL tutorials - https://ashishkingdom.github.io/OpenGL-Tutorials

Offline Ashish

  • Forum Resident
  • Posts: 630
  • Never Give Up!
    • View Profile
Re: GL Sphere
« Reply #5 on: March 08, 2019, 11:11:11 am »
Ok I see. You should avoid using glTranslatef() for a particular type of object. I recommend you to change the value of vertices of sphere to make it moving. glTranslatef() actually shift the origin from where the all the objects are drawn.
if (Me.success) {Me.improve()} else {Me.tryAgain()}


My Projects - https://github.com/AshishKingdom?tab=repositories
OpenGL tutorials - https://ashishkingdom.github.io/OpenGL-Tutorials

Offline Craz1000

  • Forum Regular
  • Posts: 111
  • I'm OK
    • View Profile
    • Craz1000.net
Re: GL Sphere
« Reply #6 on: March 08, 2019, 11:22:26 am »
here is the full bas. yea i need something like "draw a sphere at x,y,z, r big" essentially, wish solidsphere had a provision to put it at a specific spot

Code: Text: [Select]
  1. DIM SHARED DONT_USE_GLH_COL_RGBA(1 TO 4) AS SINGLE
  2.  
  3. TYPE DONT_USE_GLH_Handle_TYPE
  4.     in_use AS _BYTE
  5.     handle AS LONG
  6. END TYPE
  7.  
  8. REDIM SHARED DONT_USE_GLH_Handle(1000) AS DONT_USE_GLH_Handle_TYPE
  9.  

Code: Text: [Select]
  1. TYPE Texture
  2.     Image AS LONG
  3.     Texture AS LONG
  4. END TYPE
  5.  
  6. TYPE Projectile
  7.     Active AS INTEGER
  8.     Radius AS DOUBLE
  9.     Animate AS INTEGER
  10.     Heading AS INTEGER
  11.     Angle AS INTEGER
  12.     PosX AS SINGLE
  13.     PosY AS SINGLE
  14.     PosZ AS SINGLE
  15.     XMod AS SINGLE
  16.     ZMod AS SINGLE
  17.     YMod AS SINGLE
  18. END TYPE
  19.  
  20. TYPE Camera
  21.     RotX AS INTEGER
  22.     RotY AS INTEGER
  23.     RotZ AS INTEGER
  24.     PosX AS SINGLE
  25.     PosY AS SINGLE
  26.     PosZ AS SINGLE
  27.     Xmod AS SINGLE
  28.     Zmod AS SINGLE
  29.     Mode AS INTEGER
  30. END TYPE
  31.  
  32. TYPE Terrain
  33.     BlockSize AS INTEGER
  34.     Blocks AS INTEGER
  35.     MaxHeight AS INTEGER
  36.     MinHeight AS INTEGER
  37.     MaxHeightChange AS INTEGER
  38.     EnableWater AS INTEGER
  39.     WaterHeight AS SINGLE
  40.     WaterSpeed AS SINGLE
  41.     MaxWaterHeight AS SINGLE
  42.     MinWaterHeight AS SINGLE
  43.     WaterTextureAnimate AS INTEGER
  44.     InitHeight AS INTEGER
  45.     AnimateClock AS _INTEGER64
  46. END TYPE
  47.  
  48. DIM SHARED Land AS Terrain
  49. Land.Blocks = 100
  50. Land.BlockSize = 10
  51.  
  52. DIM SHARED Cam AS Camera
  53. DIM SHARED Fire AS Projectile
  54. DIM SHARED Heightmap(Land.Blocks + 1, Land.Blocks + 1)
  55. DIM SHARED Matrix(6) AS DOUBLE
  56. DIM SHARED AllowSubGL
  57. DIM SHARED TexturesLoaded
  58. DIM SHARED Grass1 AS Texture
  59. DIM SHARED Grass2 AS Texture
  60. DIM SHARED Grass3 AS Texture
  61. DIM SHARED Grass4 AS Texture
  62. DIM SHARED Water AS Texture
  63. DIM SHARED Rocks AS Texture
  64. DIM SHARED Dirt1 AS Texture
  65.  
  66. RANDOMIZE TIMER
  67.  

Code: Text: [Select]
  1. 'dont forget to remove the devtools when you are done
  2.  
  3. '$INCLUDE:'OpenGL_Tools.bh'
  4. '$INCLUDE:'Tanks7.bh'
  5.  
  6.  
  7. SCREEN _NEWIMAGE(1280, 720, 32)
  8. CALL LoadTextures
  9. CALL InitTerrain
  10. CALL RandomizeHeightMap
  11. CALL SetCamera
  12. BG& = _SNDOPEN("Sounds\Wind.mp3")
  13. sfx& = _SNDOPEN("stepwlk3.wav")
  14. Fire.Radius = 20
  15.  
  16. 'CALL Keylookup 'DevTool
  17.  
  18. AllowSubGL = 1
  19.  
  20. _SNDLOOP BG&
  21.  
  22. DO
  23.     _LIMIT 60
  24.     LOCATE 1, 1
  25.     PRINT "Camera Position = CamPosX:"; Cam.PosX; "Cam.PosY"; Cam.PosY; "Cam.PosZ:"; Cam.PosZ; "                     "
  26.     PRINT "Camera Aim = Cam.RotX:"; Cam.RotX; "Cam.RotY"; Cam.RotY; " Mode:"; Cam.Mode; "Clock:"; Land.AnimateClock; "                        "
  27.  
  28.     IF _KEYDOWN(49) THEN Cam.Mode = 1
  29.     IF _KEYDOWN(50) THEN Cam.Mode = 2
  30.     IF _KEYDOWN(51) THEN Cam.Mode = 3
  31.     IF _KEYDOWN(52) THEN Fire.Active = 1
  32.  
  33.  
  34.     IF _KEYDOWN(119) <> -1 AND _SNDPLAYING(sfx&) = -1 THEN
  35.         _SNDSTOP sfx&
  36.         playing = 0
  37.     END IF
  38.  
  39.  
  40.     IF _KEYDOWN(119) THEN
  41.         IF playing = 0 THEN _SNDLOOP sfx&: playing = 1
  42.         Cam.PosX = Cam.PosX - (Cam.Xmod * .5)
  43.         Cam.PosZ = Cam.PosZ - (Cam.Zmod * .5)
  44.     END IF
  45.  
  46.     IF _KEYDOWN(115) THEN
  47.         Cam.PosX = Cam.PosX + (Cam.Xmod * .5)
  48.         Cam.PosZ = Cam.PosZ + (Cam.Zmod * .5)
  49.     END IF
  50.  
  51.     DO WHILE _MOUSEINPUT
  52.         Cam.RotY = Cam.RotY + _MOUSEMOVEMENTX
  53.         IF Cam.RotY > 359 THEN Cam.RotY = 0
  54.         IF Cam.RotY < 0 THEN Cam.RotY = 359
  55.  
  56.         IF Cam.RotY = 0 THEN Cam.Xmod = 0: Cam.Zmod = -1
  57.         IF Cam.RotY > 0 AND Cam.RotY < 91 THEN Cam.Xmod = Cam.RotY / 90
  58.         IF Cam.RotY > 90 AND Cam.RotY < 181 THEN Cam.Xmod = 1 - ((Cam.RotY - 90) / 90)
  59.         IF Cam.RotY > 180 AND Cam.RotY < 271 THEN Cam.Xmod = 2 - (Cam.RotY / 90)
  60.         IF Cam.RotY > 270 AND Cam.RotY < 360 THEN Cam.Xmod = -1 + ((Cam.RotY - 270) / 90)
  61.  
  62.         IF Cam.RotY > 90 AND Cam.RotY < 181 THEN Cam.Zmod = (Cam.RotY - 90) / 90
  63.         IF Cam.RotY > 180 AND Cam.RotY < 271 THEN Cam.Zmod = 1 - ((Cam.RotY - 180) / 90)
  64.         IF Cam.RotY > 270 AND Cam.RotY < 360 THEN Cam.Zmod = 2 - ((Cam.RotY - 90) / 90)
  65.         IF Cam.RotY > 0 AND Cam.RotY < 91 THEN Cam.Zmod = -1 + (Cam.RotY / 90)
  66.  
  67.         'Cam.RotX = _MOUSEY / 10
  68.         IF _MOUSEWHEEL = -1 THEN Cam.PosY = Cam.PosY - 1
  69.         IF _MOUSEWHEEL = 1 THEN Cam.PosY = Cam.PosY + 1
  70.     LOOP
  71.  
  72.     CALL CheckCameraBoundary
  73.     CALL AnimateWater
  74. LOOP UNTIL _KEYDOWN(27)
  75. END
  76.  
  77.  
  78. SUB LoadTextures
  79.     Grass1.Image = _LOADIMAGE("Textures\00005.jpg", 32)
  80.     Grass2.Image = _LOADIMAGE("Textures\00006.jpg", 32)
  81.     Grass3.Image = _LOADIMAGE("Textures\00007.jpg", 32)
  82.     Grass4.Image = _LOADIMAGE("Textures\00008.jpg", 32)
  83.     Water.Image = _LOADIMAGE("Textures\001.jpg", 32)
  84.     Rocks.Image = _LOADIMAGE("Textures\00001.jpg", 32)
  85.     Dirt1.Image = _LOADIMAGE("Textures\00002.jpg", 32)
  86. END SUB
  87.  
  88.  
  89. SUB CheckCameraBoundary
  90.     IF Cam.PosX > -1 THEN Cam.PosX = -1
  91.     IF Cam.PosZ > -1 THEN Cam.PosZ = -1
  92.     IF Cam.PosX < -1 * (Land.Blocks * Land.BlockSize) THEN Cam.PosX = -1 * (Land.Blocks * Land.BlockSize)
  93.     IF Cam.PosZ < -1 * (Land.Blocks * Land.BlockSize) THEN Cam.PosZ = -1 * (Land.Blocks * Land.BlockSize)
  94.  
  95.     IF Cam.Mode = 1 THEN
  96.         IF (-1 * GetHeight!(Cam.PosX, Cam.PosZ)) < Land.WaterHeight THEN
  97.             Cam.PosY = -1 * (GetHeight!(Cam.PosX, Cam.PosZ)) - 2.5
  98.         ELSE
  99.             Cam.PosY = (-1 * Land.WaterHeight) - 2.5
  100.         END IF
  101.     END IF
  102.  
  103.     IF Cam.Mode = 2 THEN
  104.         IF Cam.PosY > -1 * (GetHeight!(Cam.PosX, Cam.PosZ)) - 2.5 THEN Cam.PosY = -1 * (GetHeight!(Cam.PosX, Cam.PosZ)) - 2.5
  105.     END IF
  106. END SUB
  107.  
  108.  
  109. SUB InitTerrain
  110.     TerrainType = 1 'INT(RND * 3) + 1
  111.     IF TerrainType = 1 THEN
  112.         'Wetlands
  113.         Land.InitHeight = 5
  114.         Land.MaxHeightChange = 2
  115.         Land.EnableWater = 1
  116.         Land.MaxHeight = 50
  117.         Land.MinHeight = -15
  118.         Land.WaterHeight = 0
  119.         Land.MaxWaterHeight = 1
  120.         Land.WaterSpeed = 0.0001
  121.         Land.WaterTextureAnimate = 1
  122.     ELSEIF TerrainType = 2 THEN
  123.         'Mountains
  124.         Land.InitHeight = 50
  125.         Land.MaxHeightChange = 15
  126.         Land.EnableWater = 0
  127.         Land.MaxHeight = 50
  128.         Land.MinHeight = -15
  129.     ELSEIF TerrainType = 3 THEN
  130.         'Graslands
  131.         Land.InitHeight = 2
  132.         Land.MaxHeightChange = 2
  133.         Land.EnableWater = 0
  134.         Land.MaxHeight = 50
  135.         Land.MinHeight = -15
  136.     END IF
  137. END SUB
  138.  
  139.  
  140. SUB SetCamera
  141.     Cam.PosX = -1 ' * ((Land.Blocks * Land.BlockSize) / 2)
  142.     Cam.PosZ = -1 ' * ((Land.Blocks * Land.BlockSize) / 2)
  143.     Cam.PosY = (-1 * GetHeight!(Cam.PosX, Cam.PosZ)) - 2.5
  144.     Cam.RotY = 0
  145.     Cam.Xmod = 0
  146.     Cam.Zmod = -1
  147.     Cam.Mode = 1
  148. END SUB
  149.  
  150.  
  151. SUB RandomizeHeightMap
  152.     Heightmap(1, 1) = 1.1 * Land.InitHeight
  153.     FOR x = 2 TO Land.Blocks + 1
  154.         Direction = INT(RND * 2) + 1
  155.         IF Direction = 2 THEN
  156.             HeightChange = RND * Land.MaxHeightChange
  157.         ELSE
  158.             HeightChange = -1 * (RND * Land.MaxHeightChange)
  159.         END IF
  160.         Heightmap(x, 1) = Heightmap(x - 1, 1) + HeightChange
  161.         IF Heightmap(x, 1) > Land.MaxHeight THEN Heightmap(x, 1) = Land.MaxHeight
  162.         IF Heightmap(x, 1) < Land.MinHeight THEN Heightmap(x, 1) = Land.MinHeight
  163.     NEXT x
  164.     FOR z = 2 TO Land.Blocks + 1
  165.         Direction = INT(RND * 2) + 1
  166.         IF Direction = 2 THEN
  167.             HeightChange = RND * Land.MaxHeightChange
  168.         ELSE
  169.             HeightChange = -1 * (RND * Land.MaxHeightChange)
  170.         END IF
  171.         Heightmap(1, z) = Heightmap(1, z - 1) + HeightChange
  172.         IF Heightmap(1, z) > Land.MaxHeight THEN Heightmap(1, z) = Land.MaxHeight
  173.         IF Heightmap(1, z) < Land.MinHeight THEN Heightmap(1, z) = Land.MinHeight
  174.     NEXT z
  175.     FOR x = 2 TO Land.Blocks + 1
  176.         FOR z = 2 TO Land.Blocks + 1
  177.             Direction = INT(RND * 2) + 1
  178.             IF Direction = 2 THEN
  179.                 HeightChange = RND * Land.MaxHeightChange
  180.             ELSE
  181.                 HeightChange = -1 * (RND * Land.MaxHeightChange)
  182.             END IF
  183.             Heightmap(x, z) = ((Heightmap(x, z - 1) + Heightmap(x - 1, z)) / 2) + HeightChange
  184.             IF Heightmap(x, z) > Land.MaxHeight THEN Heightmap(x, z) = Land.MaxHeight
  185.             IF Heightmap(x, z) < Land.MinHeight THEN Heightmap(x, z) = Land.MinHeight
  186.         NEXT z
  187.     NEXT x
  188. END SUB
  189.  
  190.  
  191. SUB AnimateWater
  192.     Land.WaterHeight = Land.WaterHeight + Land.WaterSpeed
  193.     IF Land.WaterHeight >= Land.MaxWaterHeight OR Land.WaterHeight <= Land.MinWaterHeight THEN Land.WaterSpeed = Land.WaterSpeed * -1
  194. END SUB
  195.  
  196.  
  197. SUB _GL STATIC
  198.     IF AllowSubGL = 0 THEN EXIT SUB
  199.  
  200.  
  201.     Land.AnimateClock = Land.AnimateClock + 1
  202.     IF Land.AnimateClock = 100 THEN Land.AnimateClock = 0
  203.  
  204.     IF Land.AnimateClock = 1 THEN Land.WaterTextureAnimate = 1
  205.     IF Land.AnimateClock = 25 THEN Land.WaterTextureAnimate = 2
  206.     IF Land.AnimateClock = 50 THEN Land.WaterTextureAnimate = 3
  207.     IF Land.AnimateClock = 75 THEN Land.WaterTextureAnimate = 4
  208.  
  209.     IF TexturesLoaded = 0 THEN
  210.         Grass1.Texture = GLH_Image_to_Texture(Grass1.Image)
  211.         Grass2.Texture = GLH_Image_to_Texture(Grass2.Image)
  212.         Grass3.Texture = GLH_Image_to_Texture(Grass3.Image)
  213.         Grass4.Texture = GLH_Image_to_Texture(Grass4.Image)
  214.         Water.Texture = GLH_Image_to_Texture(Water.Image)
  215.         _FREEIMAGE Grass1.Image
  216.         _FREEIMAGE Grass2.Image
  217.         _FREEIMAGE Grass3.Image
  218.         _FREEIMAGE Grass4.Image
  219.         _FREEIMAGE Water.Image
  220.         TexturesLoaded = 1
  221.     END IF
  222.  
  223.     _glMatrixMode _GL_PROJECTION
  224.     _glLoadIdentity
  225.     _gluPerspective 50, _WIDTH(0) / _HEIGHT(0), 1, 500
  226.     _glEnable _GL_TEXTURE_2D
  227.     _glEnable _GL_BLEND
  228.     _glEnable _GL_DEPTH_TEST
  229.     _glBlendFunc _GL_SRC_ALPHA, _GL_ONE_MINUS_SRC_ALPHA
  230.     _glEnable _GL_DEPTH_TEST
  231.     _glDepthMask _GL_TRUE
  232.     _glAlphaFunc _GL_GREATER, 0.5
  233.     _glEnable _GL_ALPHA_TEST
  234.     _glTexParameteri _GL_TEXTURE_2D, _GL_TEXTURE_MAG_FILTER, _GL_LINEAR
  235.     _glTexParameteri _GL_TEXTURE_2D, _GL_TEXTURE_MIN_FILTER, _GL_LINEAR
  236.  
  237.  
  238.     GLH_Select_Texture Grass2.Texture
  239.  
  240.  
  241.     '_glLoadIdentity
  242.     _glMatrixMode _GL_MODELVIEW
  243.     _glPushMatrix
  244.     _glRotatef Cam.RotY, 0, 1, 0
  245.     _glRotatef Cam.RotX, 1, 0, 0
  246.     _glRotatef Cam.RotZ, 0, 0, 1
  247.     _glTranslatef Cam.PosX, Cam.PosY, Cam.PosZ
  248.  
  249.     _glTexParameteri _GL_TEXTURE_2D, _GL_TEXTURE_MIN_FILTER, _GL_LINEAR
  250.     _glTexParameteri _GL_TEXTURE_2D, _GL_TEXTURE_MAG_FILTER, _GL_LINEAR
  251.  
  252.  
  253.     FOR z = 0 TO Land.Blocks - 1
  254.         FOR x = 0 TO Land.Blocks - 1
  255.             _glBegin _GL_QUADS
  256.             _glTexCoord2f 0, 0: _glVertex3f Land.BlockSize * x, Heightmap(x + 1, z + 2), Land.BlockSize * (z + 1)
  257.             _glTexCoord2f 1, 0: _glVertex3f Land.BlockSize * (x + 1), Heightmap(x + 2, z + 2), Land.BlockSize * (z + 1)
  258.             _glTexCoord2f 1, 1: _glVertex3f Land.BlockSize * (x + 1), Heightmap(x + 2, z + 1), Land.BlockSize * z
  259.             _glTexCoord2f 0, 1: _glVertex3f Land.BlockSize * x, Heightmap(x + 1, z + 1), Land.BlockSize * z
  260.             _glEnd
  261.         NEXT x
  262.     NEXT z
  263.  
  264.     GLH_Select_Texture Water.Texture
  265.  
  266.     IF Land.EnableWater = 1 THEN
  267.         FOR x = 0 TO Land.BlockSize * Land.Blocks STEP Land.BlockSize * 10
  268.             FOR z = 0 TO Land.BlockSize * Land.Blocks STEP Land.BlockSize * 10
  269.                 _glBegin _GL_QUADS
  270.                 IF Land.WaterTextureAnimate = 1 THEN
  271.                     _glTexCoord2f 0, 0: _glVertex3f x, Land.WaterHeight, z
  272.                     _glTexCoord2f 1, 0: _glVertex3f x + (Land.BlockSize * 10), Land.WaterHeight, z
  273.                     _glTexCoord2f 1, 1: _glVertex3f x + (Land.BlockSize * 10), Land.WaterHeight, z + (Land.BlockSize * 10)
  274.                     _glTexCoord2f 0, 1: _glVertex3f x, Land.WaterHeight, z + (Land.BlockSize * 10)
  275.                 ELSEIF Land.WaterTextureAnimate = 2 THEN
  276.                     _glTexCoord2f 0, 1: _glVertex3f x, Land.WaterHeight, z
  277.                     _glTexCoord2f 0, 0: _glVertex3f x + (Land.BlockSize * 10), Land.WaterHeight, z
  278.                     _glTexCoord2f 1, 0: _glVertex3f x + (Land.BlockSize * 10), Land.WaterHeight, z + (Land.BlockSize * 10)
  279.                     _glTexCoord2f 1, 1: _glVertex3f x, Land.WaterHeight, z + (Land.BlockSize * 10)
  280.                 ELSEIF Land.WaterTextureAnimate = 3 THEN
  281.                     _glTexCoord2f 1, 1: _glVertex3f x, Land.WaterHeight, z
  282.                     _glTexCoord2f 0, 1: _glVertex3f x + (Land.BlockSize * 10), Land.WaterHeight, z
  283.                     _glTexCoord2f 0, 0: _glVertex3f x + (Land.BlockSize * 10), Land.WaterHeight, z + (Land.BlockSize * 10)
  284.                     _glTexCoord2f 1, 0: _glVertex3f x, Land.WaterHeight, z + (Land.BlockSize * 10)
  285.                 ELSEIF Land.WaterTextureAnimate = 4 THEN
  286.                     _glTexCoord2f 1, 0: _glVertex3f x, Land.WaterHeight, z
  287.                     _glTexCoord2f 1, 1: _glVertex3f x + (Land.BlockSize * 10), Land.WaterHeight, z
  288.                     _glTexCoord2f 0, 1: _glVertex3f x + (Land.BlockSize * 10), Land.WaterHeight, z + (Land.BlockSize * 10)
  289.                     _glTexCoord2f 0, 0: _glVertex3f x, Land.WaterHeight, z + (Land.BlockSize * 10)
  290.                 END IF
  291.                 _glEnd
  292.  
  293.             NEXT z
  294.         NEXT x
  295.     END IF
  296.     _glPopMatrix
  297.     IF Fire.Active > 0 THEN
  298.         IF Fire.Active = 1 THEN
  299.             Fire.Animate = Fire.Animate + 1
  300.         ELSE
  301.             Fire.Animate = Fire.Animate - 1
  302.         END IF
  303.         _glMatrixMode _GL_MODELVIEW
  304.         _glPushMatrix
  305.         '_glTranslatef ABS(Cam.PosX), 0, ABS(Cam.PosZ)
  306.         _glTranslatef -100, GetHeight!(-100, -100), -100
  307.         glutSolidSphere Fire.Animate, 50, 50
  308.         _glPopMatrix
  309.  
  310.  
  311.         IF Fire.Animate = Fire.Radius THEN Fire.Active = 2
  312.         IF Fire.Animate = 0 THEN Fire.Active = 0
  313.     END IF
  314. END SUB
  315.  
  316.  
  317.  
  318. '$include:'OpenGL_Tools.bas'
  319.  

Code: Text: [Select]
  1. FUNCTION GetHeight! (Tx, Tz)
  2.     MatrixX = ABS(INT(Tx / Land.BlockSize))
  3.     MatrixZ = ABS(INT(Tz / Land.BlockSize))
  4.  
  5.     SquareX = 1 - ((Tx / Land.BlockSize) + MatrixX)
  6.     SquareZ = 1 - ((Tz / Land.BlockSize) + MatrixZ)
  7.  
  8.     Triangle = 1
  9.     IF SquareZ < 1 - SquareX THEN Triangle = 2
  10.  
  11.     IF Triangle = 2 THEN
  12.         x1 = -1 * ((MatrixX - 1) * Land.BlockSize)
  13.         x2 = -1 * (MatrixX * Land.BlockSize)
  14.         x3 = -1 * ((MatrixX - 1) * Land.BlockSize)
  15.         z1 = -1 * ((MatrixZ - 1) * Land.BlockSize)
  16.         z2 = -1 * ((MatrixZ - 1) * Land.BlockSize)
  17.         z3 = -1 * (MatrixZ * Land.BlockSize)
  18.         y1 = Heightmap(MatrixX, MatrixZ)
  19.         y2 = Heightmap(MatrixX + 1, MatrixZ)
  20.         y3 = Heightmap(MatrixX, MatrixZ + 1)
  21.     END IF
  22.  
  23.     IF Triangle = 1 THEN
  24.         x1 = -1 * (MatrixX * Land.BlockSize)
  25.         x2 = -1 * (MatrixX * Land.BlockSize)
  26.         x3 = -1 * ((MatrixX - 1) * Land.BlockSize)
  27.         z1 = -1 * (MatrixZ * Land.BlockSize)
  28.         z2 = -1 * ((MatrixZ - 1) * Land.BlockSize)
  29.         z3 = -1 * (MatrixZ * Land.BlockSize)
  30.         y1 = Heightmap(MatrixX + 1, MatrixZ + 1)
  31.         y2 = Heightmap(MatrixX + 1, MatrixZ)
  32.         y3 = Heightmap(MatrixX, MatrixZ + 1)
  33.     END IF
  34.  
  35.     A = y1 * (z2 - z3) + y2 * (z3 - z1) + y3 * (z1 - z2)
  36.     B = z1 * (x2 - x3) + z2 * (x3 - x1) + z3 * (x1 - x2)
  37.     C = x1 * (y2 - y3) + x2 * (y3 - y1) + x3 * (y1 - y2)
  38.     D = 0 - (x1 * (y2 * z3 - y3 * z2) + x2 * (y3 * z1 - y1 * z3) + x3 * (y1 * z2 - y2 * z1))
  39.     GetHeight = 0 - (D + A * Tx + C * Tz) / B
  40. END FUNCTION
  41.  
  42. SUB GLH_Select_Texture (texture_handle AS LONG) 'turn an image handle into a texture handle
  43.     IF texture_handle < 1 OR texture_handle > UBOUND(DONT_USE_GLH_HANDLE) THEN ERROR 258: EXIT FUNCTION
  44.     IF DONT_USE_GLH_Handle(texture_handle).in_use = 0 THEN ERROR 258: EXIT FUNCTION
  45.     _glBindTexture _GL_TEXTURE_2D, DONT_USE_GLH_Handle(texture_handle).handle
  46. END SUB
  47.  
  48. FUNCTION GLH_Image_to_Texture (image_handle AS LONG) 'turn an image handle into a texture handle
  49.     IF image_handle >= 0 THEN ERROR 258: EXIT FUNCTION 'don't allow screen pages
  50.     DIM m AS _MEM
  51.     m = _MEMIMAGE(image_handle)
  52.     DIM h AS LONG
  53.     h = DONT_USE_GLH_New_Texture_Handle
  54.     GLH_Image_to_Texture = h
  55.     _glBindTexture _GL_TEXTURE_2D, DONT_USE_GLH_Handle(h).handle
  56.     _glTexImage2D _GL_TEXTURE_2D, 0, _GL_RGBA, _WIDTH(image_handle), _HEIGHT(image_handle), 0, &H80E1&&, _GL_UNSIGNED_BYTE, m.OFFSET
  57.     _MEMFREE m
  58. END FUNCTION
  59.  
  60. FUNCTION DONT_USE_GLH_New_Texture_Handle
  61.     handle&& = 0
  62.     _glGenTextures 1, _OFFSET(handle&&)
  63.     DONT_USE_GLH_New_Texture_Handle = handle&&
  64.     FOR h = 1 TO UBOUND(DONT_USE_GLH_Handle)
  65.         IF DONT_USE_GLH_Handle(h).in_use = 0 THEN
  66.             DONT_USE_GLH_Handle(h).in_use = 1
  67.             DONT_USE_GLH_Handle(h).handle = handle&&
  68.             DONT_USE_GLH_New_Texture_Handle = h
  69.             EXIT FUNCTION
  70.         END IF
  71.     NEXT
  72.     REDIM _PRESERVE DONT_USE_GLH_Handle(UBOUND(DONT_USE_GLH_HANDLE) * 2) AS DONT_USE_GLH_Handle_TYPE
  73.     DONT_USE_GLH_Handle(h).in_use = 1
  74.     DONT_USE_GLH_Handle(h).handle = handle&&
  75.     DONT_USE_GLH_New_Texture_Handle = h
  76. END FUNCTION
  77.  
  78. FUNCTION GLH_RGB%& (r AS SINGLE, g AS SINGLE, b AS SINGLE)
  79.     DONT_USE_GLH_COL_RGBA(1) = r
  80.     DONT_USE_GLH_COL_RGBA(2) = g
  81.     DONT_USE_GLH_COL_RGBA(3) = b
  82.     DONT_USE_GLH_COL_RGBA(4) = 1
  83.     GLH_RGB = _OFFSET(DONT_USE_GLH_COL_RGBA())
  84. END FUNCTION
  85.  
  86. FUNCTION GLH_RGBA%& (r AS SINGLE, g AS SINGLE, b AS SINGLE, a AS SINGLE)
  87.     DONT_USE_GLH_COL_RGBA(1) = r
  88.     DONT_USE_GLH_COL_RGBA(2) = g
  89.     DONT_USE_GLH_COL_RGBA(3) = b
  90.     DONT_USE_GLH_COL_RGBA(4) = a
  91.     GLH_RGBA = _OFFSET(DONT_USE_GLH_COL_RGBA())
  92. END FUNCTION
  93.  
« Last Edit: March 08, 2019, 11:30:32 am by Craz1000 »

Offline Craz1000

  • Forum Regular
  • Posts: 111
  • I'm OK
    • View Profile
    • Craz1000.net
Re: GL Sphere
« Reply #7 on: March 08, 2019, 12:53:33 pm »
so i edited freeglut_geometry.c and sphere is still drawn at origin, crashes at times as well

Code: QB64: [Select]
  1. #ifndef FREEGLUT_STATIC
  2. #define FREEGLUT_STATIC
  3. #endif
  4. /*
  5.  * freeglut_geometry.c
  6.  *
  7.  * Freeglut geometry rendering methods.
  8.  *
  9.  * Copyright (c) 1999-2000 Pawel W. Olszta. All Rights Reserved.
  10.  * Written by Pawel W. Olszta, <olszta@sourceforge.net>
  11.  * Creation date: Fri Dec 3 1999
  12.  *
  13.  * Permission is hereby granted, free of charge, to any person obtaining a
  14.  * copy of this software and associated documentation files (the "Software"),
  15.  * to deal in the Software without restriction, including without limitation
  16.  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  17.  * and/or sell copies of the Software, and to permit persons to whom the
  18.  * Software is furnished to do so, subject to the following conditions:
  19.  *
  20.  * The above copyright notice and this permission notice shall be included
  21.  * in all copies or substantial portions of the Software.
  22.  *
  23.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  24.  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  25.  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  26.  * PAWEL W. OLSZTA BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
  27.  * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  28.  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  29.  */
  30.  
  31. #include "freeglut.h"
  32. #include "freeglut_internal.h"
  33.  
  34. /*
  35.  * TODO BEFORE THE STABLE RELEASE:
  36.  *
  37.  * Following functions have been contributed by Andreas Umbach.
  38.  *
  39.  *      glutWireCube()          -- looks OK
  40.  *      glutSolidCube()         -- OK
  41.  *
  42.  * Those functions have been implemented by John Fay.
  43.  *
  44.  *      glutWireTorus()         -- looks OK
  45.  *      glutSolidTorus()        -- looks OK
  46.  *      glutWireDodecahedron()  -- looks OK
  47.  *      glutSolidDodecahedron() -- looks OK
  48.  *      glutWireOctahedron()    -- looks OK
  49.  *      glutSolidOctahedron()   -- looks OK
  50.  *      glutWireTetrahedron()   -- looks OK
  51.  *      glutSolidTetrahedron()  -- looks OK
  52.  *      glutWireIcosahedron()   -- looks OK
  53.  *      glutSolidIcosahedron()  -- looks OK
  54.  *
  55.  *  The Following functions have been updated by Nigel Stewart, based
  56.  *  on FreeGLUT 2.0.0 implementations:
  57.  *
  58.  *      glutWireSphere()        -- looks OK
  59.  *      glutSolidSphere()       -- looks OK
  60.  *      glutWireCone()          -- looks OK
  61.  *      glutSolidCone()         -- looks OK
  62.  */
  63.  
  64.  
  65. /* -- INTERFACE FUNCTIONS -------------------------------------------------- */
  66.  
  67. /*
  68.  * Draws a wireframed cube. Code contributed by Andreas Umbach <marvin@dataway.ch>
  69.  */
  70. void FGAPIENTRY glutWireCube( GLdouble dSize )
  71. {
  72.     double size = dSize * 0.5;
  73.  
  74.     FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutWireCube" );
  75.  
  76. #   define V(a,b,c) glVertex3d( a size, b size, c size );
  77. #   define N(a,b,c) glNormal3d( a, b, c );
  78.  
  79.     /* PWO: I dared to convert the code to use macros... */
  80.     glBegin( GL_LINE_LOOP ); N( 1.0, 0.0, 0.0); V(+,-,+); V(+,-,-); V(+,+,-); V(+,+,+); glEnd();
  81.     glBegin( GL_LINE_LOOP ); N( 0.0, 1.0, 0.0); V(+,+,+); V(+,+,-); V(-,+,-); V(-,+,+); glEnd();
  82.     glBegin( GL_LINE_LOOP ); N( 0.0, 0.0, 1.0); V(+,+,+); V(-,+,+); V(-,-,+); V(+,-,+); glEnd();
  83.     glBegin( GL_LINE_LOOP ); N(-1.0, 0.0, 0.0); V(-,-,+); V(-,+,+); V(-,+,-); V(-,-,-); glEnd();
  84.     glBegin( GL_LINE_LOOP ); N( 0.0,-1.0, 0.0); V(-,-,+); V(-,-,-); V(+,-,-); V(+,-,+); glEnd();
  85.     glBegin( GL_LINE_LOOP ); N( 0.0, 0.0,-1.0); V(-,-,-); V(-,+,-); V(+,+,-); V(+,-,-); glEnd();
  86.  
  87. #   undef V
  88. #   undef N
  89. }
  90.  
  91. /*
  92.  * Draws a solid cube. Code contributed by Andreas Umbach <marvin@dataway.ch>
  93.  */
  94. void FGAPIENTRY glutSolidCube( GLdouble dSize )
  95. {
  96.     double size = dSize * 0.5;
  97.  
  98.     FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutSolidCube" );
  99.  
  100. #   define V(a,b,c) glVertex3d( a size, b size, c size );
  101. #   define N(a,b,c) glNormal3d( a, b, c );
  102.  
  103.     /* PWO: Again, I dared to convert the code to use macros... */
  104.     glBegin( GL_QUADS );
  105.         N( 1.0, 0.0, 0.0); V(+,-,+); V(+,-,-); V(+,+,-); V(+,+,+);
  106.         N( 0.0, 1.0, 0.0); V(+,+,+); V(+,+,-); V(-,+,-); V(-,+,+);
  107.         N( 0.0, 0.0, 1.0); V(+,+,+); V(-,+,+); V(-,-,+); V(+,-,+);
  108.         N(-1.0, 0.0, 0.0); V(-,-,+); V(-,+,+); V(-,+,-); V(-,-,-);
  109.         N( 0.0,-1.0, 0.0); V(-,-,+); V(-,-,-); V(+,-,-); V(+,-,+);
  110.         N( 0.0, 0.0,-1.0); V(-,-,-); V(-,+,-); V(+,+,-); V(+,-,-);
  111.     glEnd();
  112.  
  113. #   undef V
  114. #   undef N
  115. }
  116.  
  117. /*
  118.  * Compute lookup table of cos and sin values forming a cirle
  119.  *
  120.  * Notes:
  121.  *    It is the responsibility of the caller to free these tables
  122.  *    The size of the table is (n+1) to form a connected loop
  123.  *    The last entry is exactly the same as the first
  124.  *    The sign of n can be flipped to get the reverse loop
  125.  */
  126.  
  127. static void fghCircleTable(double **sint,double **cost,const int n)
  128. {
  129.     int i;
  130.  
  131.     /* Table size, the sign of n flips the circle direction */
  132.  
  133.     const int size = abs(n);
  134.  
  135.     /* Determine the angle between samples */
  136.  
  137.     const double angle = 2*M_PI/(double)( ( n == 0 ) ? 1 : n );
  138.  
  139.     /* Allocate memory for n samples, plus duplicate of first entry at the end */
  140.  
  141.     *sint = (double *) calloc(sizeof(double), size+1);
  142.     *cost = (double *) calloc(sizeof(double), size+1);
  143.  
  144.     /* Bail out if memory allocation fails, fgError never returns */
  145.  
  146.     if (!(*sint) || !(*cost))
  147.     {
  148.         free(*sint);
  149.         free(*cost);
  150.         fgError("Failed to allocate memory in fghCircleTable");
  151.     }
  152.  
  153.     /* Compute cos and sin around the circle */
  154.  
  155.     (*sint)[0] = 0.0;
  156.     (*cost)[0] = 1.0;
  157.  
  158.     for (i=1; i<size; i++)
  159.     {
  160.         (*sint)[i] = sin(angle*i);
  161.         (*cost)[i] = cos(angle*i);
  162.     }
  163.  
  164.     /* Last sample is duplicate of the first */
  165.  
  166.     (*sint)[size] = (*sint)[0];
  167.     (*cost)[size] = (*cost)[0];
  168. }
  169.  
  170. /*
  171.  * Draws a solid sphere
  172.  */
  173. void FGAPIENTRY glutSolidSphere(GLdouble radius, GLint slices, GLint stacks, GLdouble PosX, GLdouble PosY, GLdouble PosZ)
  174. {
  175.     int i,j;
  176.  
  177.     /* Adjust z and radius as stacks are drawn. */
  178.  
  179.     double z0,z1;
  180.     double r0,r1;
  181.  
  182.     /* Pre-computed circle */
  183.  
  184.     double *sint1,*cost1;
  185.     double *sint2,*cost2;
  186.  
  187.     FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutSolidSphere" );
  188.  
  189.     fghCircleTable(&sint1,&cost1,-slices);
  190.     fghCircleTable(&sint2,&cost2,stacks*2);
  191.  
  192.     /* The top stack is covered with a triangle fan */
  193.  
  194.     z0 = 1.0;
  195.     z1 = cost2[(stacks>0)?1:0];
  196.     r0 = 0.0;
  197.     r1 = sint2[(stacks>0)?1:0];
  198.  
  199.     glBegin(GL_TRIANGLE_FAN);
  200.  
  201.         glNormal3d(PosX,PosY,PosZ+1);
  202.         glVertex3d(PosX,PosY,radius);
  203.  
  204.         for (j=slices; j>=0; j--)
  205.         {
  206.             glNormal3d(PosX+(cost1[j]*r1),        PosY+(sint1[j]*r1),        PosZ+z1       );
  207.             glVertex3d(PosX+(cost1[j]*r1*radius), PosY+(sint1[j]*r1*radius), PosZ+(z1*radius));
  208.         }
  209.  
  210.     glEnd();
  211.  
  212.     /* Cover each stack with a quad strip, except the top and bottom stacks */
  213.  
  214.     for( i=1; i<stacks-1; i++ )
  215.     {
  216.         z0 = z1; z1 = cost2[i+1];
  217.         r0 = r1; r1 = sint2[i+1];
  218.  
  219.         glBegin(GL_QUAD_STRIP);
  220.  
  221.             for(j=0; j<=slices; j++)
  222.             {
  223.                 glNormal3d(PosX+(cost1[j]*r1),        PosY+(sint1[j]*r1),        PosZ+z1       );
  224.                 glVertex3d(PosX+(cost1[j]*r1*radius), PosY+(sint1[j]*r1*radius), PosZ+(z1*radius));
  225.                 glNormal3d(PosX+(cost1[j]*r0),        PosY+(sint1[j]*r0),        PosZ+z0       );
  226.                 glVertex3d(PosX+(cost1[j]*r0*radius), PosY+(sint1[j]*r0*radius), PosZ+(z0*radius));
  227.             }
  228.  
  229.         glEnd();
  230.     }
  231.  
  232.     /* The bottom stack is covered with a triangle fan */
  233.  
  234.     z0 = z1;
  235.     r0 = r1;
  236.  
  237.     glBegin(GL_TRIANGLE_FAN);
  238.  
  239.         glNormal3d(PosX,PosY,PosZ-1);
  240.         glVertex3d(PosX,PosY,PosZ-radius);
  241.  
  242.         for (j=0; j<=slices; j++)
  243.         {
  244.             glNormal3d(PosX+(cost1[j]*r0),        PosY+(sint1[j]*r0),        PosZ+z0       );
  245.             glVertex3d(PosX+(cost1[j]*r0*radius), PosY+(sint1[j]*r0*radius), PosZ+(z0*radius));
  246.         }
  247.  
  248.     glEnd();
  249.  
  250.     /* Release sin and cos tables */
  251.  
  252.     free(sint1);
  253.     free(cost1);
  254.     free(sint2);
  255.     free(cost2);
  256. }
  257.  
  258. /*
  259.  * Draws a wire sphere
  260.  */
  261. void FGAPIENTRY glutWireSphere(GLdouble radius, GLint slices, GLint stacks)
  262. {
  263.     int i,j;
  264.  
  265.     /* Adjust z and radius as stacks and slices are drawn. */
  266.  
  267.     double r;
  268.     double x,y,z;
  269.  
  270.     /* Pre-computed circle */
  271.  
  272.     double *sint1,*cost1;
  273.     double *sint2,*cost2;
  274.  
  275.     FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutWireSphere" );
  276.  
  277.     fghCircleTable(&sint1,&cost1,-slices  );
  278.     fghCircleTable(&sint2,&cost2, stacks*2);
  279.  
  280.     /* Draw a line loop for each stack */
  281.  
  282.     for (i=1; i<stacks; i++)
  283.     {
  284.         z = cost2[i];
  285.         r = sint2[i];
  286.  
  287.         glBegin(GL_LINE_LOOP);
  288.  
  289.             for(j=0; j<=slices; j++)
  290.             {
  291.                 x = cost1[j];
  292.                 y = sint1[j];
  293.  
  294.                 glNormal3d(x,y,z);
  295.                 glVertex3d(x*r*radius,y*r*radius,z*radius);
  296.             }
  297.  
  298.         glEnd();
  299.     }
  300.  
  301.     /* Draw a line loop for each slice */
  302.  
  303.     for (i=0; i<slices; i++)
  304.     {
  305.         glBegin(GL_LINE_STRIP);
  306.  
  307.             for(j=0; j<=stacks; j++)
  308.             {
  309.                 x = cost1[i]*sint2[j];
  310.                 y = sint1[i]*sint2[j];
  311.                 z = cost2[j];
  312.  
  313.                 glNormal3d(x,y,z);
  314.                 glVertex3d(x*radius,y*radius,z*radius);
  315.             }
  316.  
  317.         glEnd();
  318.     }
  319.  
  320.     /* Release sin and cos tables */
  321.  
  322.     free(sint1);
  323.     free(cost1);
  324.     free(sint2);
  325.     free(cost2);
  326. }
  327.  
  328. /*
  329.  * Draws a solid cone
  330.  */
  331. void FGAPIENTRY glutSolidCone( GLdouble base, GLdouble height, GLint slices, GLint stacks )
  332. {
  333.     int i,j;
  334.  
  335.     /* Step in z and radius as stacks are drawn. */
  336.  
  337.     double z0,z1;
  338.     double r0,r1;
  339.  
  340.     const double zStep = height / ( ( stacks > 0 ) ? stacks : 1 );
  341.     const double rStep = base / ( ( stacks > 0 ) ? stacks : 1 );
  342.  
  343.     /* Scaling factors for vertex normals */
  344.  
  345.     const double cosn = ( height / sqrt ( height * height + base * base ));
  346.     const double sinn = ( base   / sqrt ( height * height + base * base ));
  347.  
  348.     /* Pre-computed circle */
  349.  
  350.     double *sint,*cost;
  351.  
  352.     FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutSolidCone" );
  353.  
  354.     fghCircleTable(&sint,&cost,-slices);
  355.  
  356.     /* Cover the circular base with a triangle fan... */
  357.  
  358.     z0 = 0.0;
  359.     z1 = zStep;
  360.  
  361.     r0 = base;
  362.     r1 = r0 - rStep;
  363.  
  364.     glBegin(GL_TRIANGLE_FAN);
  365.  
  366.         glNormal3d(0.0,0.0,-1.0);
  367.         glVertex3d(0.0,0.0, z0 );
  368.  
  369.         for (j=0; j<=slices; j++)
  370.             glVertex3d(cost[j]*r0, sint[j]*r0, z0);
  371.  
  372.     glEnd();
  373.  
  374.     /* Cover each stack with a quad strip, except the top stack */
  375.  
  376.     for( i=0; i<stacks-1; i++ )
  377.     {
  378.         glBegin(GL_QUAD_STRIP);
  379.  
  380.             for(j=0; j<=slices; j++)
  381.             {
  382.                 glNormal3d(cost[j]*cosn, sint[j]*cosn, sinn);
  383.                 glVertex3d(cost[j]*r0,   sint[j]*r0,   z0  );
  384.                 glVertex3d(cost[j]*r1,   sint[j]*r1,   z1  );
  385.             }
  386.  
  387.             z0 = z1; z1 += zStep;
  388.             r0 = r1; r1 -= rStep;
  389.  
  390.         glEnd();
  391.     }
  392.  
  393.     /* The top stack is covered with individual triangles */
  394.  
  395.     glBegin(GL_TRIANGLES);
  396.  
  397.         glNormal3d(cost[0]*sinn, sint[0]*sinn, cosn);
  398.  
  399.         for (j=0; j<slices; j++)
  400.         {
  401.             glVertex3d(cost[j+0]*r0,   sint[j+0]*r0,   z0    );
  402.             glVertex3d(0,              0,              height);
  403.             glNormal3d(cost[j+1]*sinn, sint[j+1]*sinn, cosn  );
  404.             glVertex3d(cost[j+1]*r0,   sint[j+1]*r0,   z0    );
  405.         }
  406.  
  407.     glEnd();
  408.  
  409.     /* Release sin and cos tables */
  410.  
  411.     free(sint);
  412.     free(cost);
  413. }
  414.  
  415. /*
  416.  * Draws a wire cone
  417.  */
  418. void FGAPIENTRY glutWireCone( GLdouble base, GLdouble height, GLint slices, GLint stacks)
  419. {
  420.     int i,j;
  421.  
  422.     /* Step in z and radius as stacks are drawn. */
  423.  
  424.     double z = 0.0;
  425.     double r = base;
  426.  
  427.     const double zStep = height / ( ( stacks > 0 ) ? stacks : 1 );
  428.     const double rStep = base / ( ( stacks > 0 ) ? stacks : 1 );
  429.  
  430.     /* Scaling factors for vertex normals */
  431.  
  432.     const double cosn = ( height / sqrt ( height * height + base * base ));
  433.     const double sinn = ( base   / sqrt ( height * height + base * base ));
  434.  
  435.     /* Pre-computed circle */
  436.  
  437.     double *sint,*cost;
  438.  
  439.     FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutWireCone" );
  440.  
  441.     fghCircleTable(&sint,&cost,-slices);
  442.  
  443.     /* Draw the stacks... */
  444.  
  445.     for (i=0; i<stacks; i++)
  446.     {
  447.         glBegin(GL_LINE_LOOP);
  448.  
  449.             for( j=0; j<slices; j++ )
  450.             {
  451.                 glNormal3d(cost[j]*sinn, sint[j]*sinn, cosn);
  452.                 glVertex3d(cost[j]*r,    sint[j]*r,    z   );
  453.             }
  454.  
  455.         glEnd();
  456.  
  457.         z += zStep;
  458.         r -= rStep;
  459.     }
  460.  
  461.     /* Draw the slices */
  462.  
  463.     r = base;
  464.  
  465.     glBegin(GL_LINES);
  466.  
  467.         for (j=0; j<slices; j++)
  468.         {
  469.             glNormal3d(cost[j]*sinn, sint[j]*sinn, cosn  );
  470.             glVertex3d(cost[j]*r,    sint[j]*r,    0.0   );
  471.             glVertex3d(0.0,          0.0,          height);
  472.         }
  473.  
  474.     glEnd();
  475.  
  476.     /* Release sin and cos tables */
  477.  
  478.     free(sint);
  479.     free(cost);
  480. }
  481.  
  482.  
  483. /*
  484.  * Draws a solid cylinder
  485.  */
  486. void FGAPIENTRY glutSolidCylinder(GLdouble radius, GLdouble height, GLint slices, GLint stacks)
  487. {
  488.     int i,j;
  489.  
  490.     /* Step in z and radius as stacks are drawn. */
  491.  
  492.     double z0,z1;
  493.     const double zStep = height / ( ( stacks > 0 ) ? stacks : 1 );
  494.  
  495.     /* Pre-computed circle */
  496.  
  497.     double *sint,*cost;
  498.  
  499.     FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutSolidCylinder" );
  500.  
  501.     fghCircleTable(&sint,&cost,-slices);
  502.  
  503.     /* Cover the base and top */
  504.  
  505.     glBegin(GL_TRIANGLE_FAN);
  506.         glNormal3d(0.0, 0.0, -1.0 );
  507.         glVertex3d(0.0, 0.0,  0.0 );
  508.         for (j=0; j<=slices; j++)
  509.           glVertex3d(cost[j]*radius, sint[j]*radius, 0.0);
  510.     glEnd();
  511.  
  512.     glBegin(GL_TRIANGLE_FAN);
  513.         glNormal3d(0.0, 0.0, 1.0   );
  514.         glVertex3d(0.0, 0.0, height);
  515.         for (j=slices; j>=0; j--)
  516.           glVertex3d(cost[j]*radius, sint[j]*radius, height);
  517.     glEnd();
  518.  
  519.     /* Do the stacks */
  520.  
  521.     z0 = 0.0;
  522.     z1 = zStep;
  523.  
  524.     for (i=1; i<=stacks; i++)
  525.     {
  526.         if (i==stacks)
  527.             z1 = height;
  528.  
  529.         glBegin(GL_QUAD_STRIP);
  530.             for (j=0; j<=slices; j++ )
  531.             {
  532.                 glNormal3d(cost[j],        sint[j],        0.0 );
  533.                 glVertex3d(cost[j]*radius, sint[j]*radius, z0  );
  534.                 glVertex3d(cost[j]*radius, sint[j]*radius, z1  );
  535.             }
  536.         glEnd();
  537.  
  538.         z0 = z1; z1 += zStep;
  539.     }
  540.  
  541.     /* Release sin and cos tables */
  542.  
  543.     free(sint);
  544.     free(cost);
  545. }
  546.  
  547. /*
  548.  * Draws a wire cylinder
  549.  */
  550. void FGAPIENTRY glutWireCylinder(GLdouble radius, GLdouble height, GLint slices, GLint stacks)
  551. {
  552.     int i,j;
  553.  
  554.     /* Step in z and radius as stacks are drawn. */
  555.  
  556.           double z = 0.0;
  557.     const double zStep = height / ( ( stacks > 0 ) ? stacks : 1 );
  558.  
  559.     /* Pre-computed circle */
  560.  
  561.     double *sint,*cost;
  562.  
  563.     FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutWireCylinder" );
  564.  
  565.     fghCircleTable(&sint,&cost,-slices);
  566.  
  567.     /* Draw the stacks... */
  568.  
  569.     for (i=0; i<=stacks; i++)
  570.     {
  571.         if (i==stacks)
  572.             z = height;
  573.  
  574.         glBegin(GL_LINE_LOOP);
  575.  
  576.             for( j=0; j<slices; j++ )
  577.             {
  578.                 glNormal3d(cost[j],        sint[j],        0.0);
  579.                 glVertex3d(cost[j]*radius, sint[j]*radius, z  );
  580.             }
  581.  
  582.         glEnd();
  583.  
  584.         z += zStep;
  585.     }
  586.  
  587.     /* Draw the slices */
  588.  
  589.     glBegin(GL_LINES);
  590.  
  591.         for (j=0; j<slices; j++)
  592.         {
  593.             glNormal3d(cost[j],        sint[j],        0.0   );
  594.             glVertex3d(cost[j]*radius, sint[j]*radius, 0.0   );
  595.             glVertex3d(cost[j]*radius, sint[j]*radius, height);
  596.         }
  597.  
  598.     glEnd();
  599.  
  600.     /* Release sin and cos tables */
  601.  
  602.     free(sint);
  603.     free(cost);
  604. }
  605.  
  606. /*
  607.  * Draws a wire torus
  608.  */
  609. void FGAPIENTRY glutWireTorus( GLdouble dInnerRadius, GLdouble dOuterRadius, GLint nSides, GLint nRings )
  610. {
  611.   double  iradius = dInnerRadius, oradius = dOuterRadius, phi, psi, dpsi, dphi;
  612.   double *vertex, *normal;
  613.   int    i, j;
  614.   double spsi, cpsi, sphi, cphi ;
  615.  
  616.   FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutWireTorus" );
  617.  
  618.   if ( nSides < 1 ) nSides = 1;
  619.   if ( nRings < 1 ) nRings = 1;
  620.  
  621.   /* Allocate the vertices array */
  622.   vertex = (double *)calloc( sizeof(double), 3 * nSides * nRings );
  623.   normal = (double *)calloc( sizeof(double), 3 * nSides * nRings );
  624.  
  625.   glPushMatrix();
  626.  
  627.   dpsi =  2.0 * M_PI / (double)nRings ;
  628.   dphi = -2.0 * M_PI / (double)nSides ;
  629.   psi  = 0.0;
  630.  
  631.   for( j=0; j<nRings; j++ )
  632.   {
  633.     cpsi = cos ( psi ) ;
  634.     spsi = sin ( psi ) ;
  635.     phi = 0.0;
  636.  
  637.     for( i=0; i<nSides; i++ )
  638.     {
  639.       int offset = 3 * ( j * nSides + i ) ;
  640.       cphi = cos ( phi ) ;
  641.       sphi = sin ( phi ) ;
  642.       *(vertex + offset + 0) = cpsi * ( oradius + cphi * iradius ) ;
  643.       *(vertex + offset + 1) = spsi * ( oradius + cphi * iradius ) ;
  644.       *(vertex + offset + 2) =                    sphi * iradius  ;
  645.       *(normal + offset + 0) = cpsi * cphi ;
  646.       *(normal + offset + 1) = spsi * cphi ;
  647.       *(normal + offset + 2) =        sphi ;
  648.       phi += dphi;
  649.     }
  650.  
  651.     psi += dpsi;
  652.   }
  653.  
  654.   for( i=0; i<nSides; i++ )
  655.   {
  656.     glBegin( GL_LINE_LOOP );
  657.  
  658.     for( j=0; j<nRings; j++ )
  659.     {
  660.       int offset = 3 * ( j * nSides + i ) ;
  661.       glNormal3dv( normal + offset );
  662.       glVertex3dv( vertex + offset );
  663.     }
  664.  
  665.     glEnd();
  666.   }
  667.  
  668.   for( j=0; j<nRings; j++ )
  669.   {
  670.     glBegin(GL_LINE_LOOP);
  671.  
  672.     for( i=0; i<nSides; i++ )
  673.     {
  674.       int offset = 3 * ( j * nSides + i ) ;
  675.       glNormal3dv( normal + offset );
  676.       glVertex3dv( vertex + offset );
  677.     }
  678.  
  679.     glEnd();
  680.   }
  681.  
  682.   free ( vertex ) ;
  683.   free ( normal ) ;
  684.   glPopMatrix();
  685. }
  686.  
  687. /*
  688.  * Draws a solid torus
  689.  */
  690. void FGAPIENTRY glutSolidTorus( GLdouble dInnerRadius, GLdouble dOuterRadius, GLint nSides, GLint nRings )
  691. {
  692.   double  iradius = dInnerRadius, oradius = dOuterRadius, phi, psi, dpsi, dphi;
  693.   double *vertex, *normal;
  694.   int    i, j;
  695.   double spsi, cpsi, sphi, cphi ;
  696.  
  697.   FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutSolidTorus" );
  698.  
  699.   if ( nSides < 1 ) nSides = 1;
  700.   if ( nRings < 1 ) nRings = 1;
  701.  
  702.   /* Increment the number of sides and rings to allow for one more point than surface */
  703.   nSides ++ ;
  704.   nRings ++ ;
  705.  
  706.   /* Allocate the vertices array */
  707.   vertex = (double *)calloc( sizeof(double), 3 * nSides * nRings );
  708.   normal = (double *)calloc( sizeof(double), 3 * nSides * nRings );
  709.  
  710.   glPushMatrix();
  711.  
  712.   dpsi =  2.0 * M_PI / (double)(nRings - 1) ;
  713.   dphi = -2.0 * M_PI / (double)(nSides - 1) ;
  714.   psi  = 0.0;
  715.  
  716.   for( j=0; j<nRings; j++ )
  717.   {
  718.     cpsi = cos ( psi ) ;
  719.     spsi = sin ( psi ) ;
  720.     phi = 0.0;
  721.  
  722.     for( i=0; i<nSides; i++ )
  723.     {
  724.       int offset = 3 * ( j * nSides + i ) ;
  725.       cphi = cos ( phi ) ;
  726.       sphi = sin ( phi ) ;
  727.       *(vertex + offset + 0) = cpsi * ( oradius + cphi * iradius ) ;
  728.       *(vertex + offset + 1) = spsi * ( oradius + cphi * iradius ) ;
  729.       *(vertex + offset + 2) =                    sphi * iradius  ;
  730.       *(normal + offset + 0) = cpsi * cphi ;
  731.       *(normal + offset + 1) = spsi * cphi ;
  732.       *(normal + offset + 2) =        sphi ;
  733.       phi += dphi;
  734.     }
  735.  
  736.     psi += dpsi;
  737.   }
  738.  
  739.     glBegin( GL_QUADS );
  740.   for( i=0; i<nSides-1; i++ )
  741.   {
  742.     for( j=0; j<nRings-1; j++ )
  743.     {
  744.       int offset = 3 * ( j * nSides + i ) ;
  745.       glNormal3dv( normal + offset );
  746.       glVertex3dv( vertex + offset );
  747.       glNormal3dv( normal + offset + 3 );
  748.       glVertex3dv( vertex + offset + 3 );
  749.       glNormal3dv( normal + offset + 3 * nSides + 3 );
  750.       glVertex3dv( vertex + offset + 3 * nSides + 3 );
  751.       glNormal3dv( normal + offset + 3 * nSides );
  752.       glVertex3dv( vertex + offset + 3 * nSides );
  753.     }
  754.   }
  755.  
  756.   glEnd();
  757.  
  758.   free ( vertex ) ;
  759.   free ( normal ) ;
  760.   glPopMatrix();
  761. }
  762.  
  763. /*
  764.  *
  765.  */
  766. void FGAPIENTRY glutWireDodecahedron( void )
  767. {
  768.   FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutWireDodecahedron" );
  769.  
  770.   /* Magic Numbers:  It is possible to create a dodecahedron by attaching two pentagons to each face of
  771.    * of a cube.  The coordinates of the points are:
  772.    *   (+-x,0, z); (+-1, 1, 1); (0, z, x )
  773.    * where x = (-1 + sqrt(5))/2, z = (1 + sqrt(5))/2  or
  774.    *       x = 0.61803398875 and z = 1.61803398875.
  775.    */
  776.   glBegin ( GL_LINE_LOOP ) ;
  777.   glNormal3d (  0.0,  0.525731112119,  0.850650808354 ) ; glVertex3d (  0.0,  1.61803398875,  0.61803398875 ) ; glVertex3d ( -1.0,  1.0,  1.0 ) ; glVertex3d ( -0.61803398875, 0.0,  1.61803398875 ) ; glVertex3d (  0.61803398875, 0.0,  1.61803398875 ) ; glVertex3d (  1.0,  1.0,  1.0 ) ;
  778.   glEnd () ;
  779.   glBegin ( GL_LINE_LOOP ) ;
  780.   glNormal3d (  0.0,  0.525731112119, -0.850650808354 ) ; glVertex3d (  0.0,  1.61803398875, -0.61803398875 ) ; glVertex3d (  1.0,  1.0, -1.0 ) ; glVertex3d (  0.61803398875, 0.0, -1.61803398875 ) ; glVertex3d ( -0.61803398875, 0.0, -1.61803398875 ) ; glVertex3d ( -1.0,  1.0, -1.0 ) ;
  781.   glEnd () ;
  782.   glBegin ( GL_LINE_LOOP ) ;
  783.   glNormal3d (  0.0, -0.525731112119,  0.850650808354 ) ; glVertex3d (  0.0, -1.61803398875,  0.61803398875 ) ; glVertex3d (  1.0, -1.0,  1.0 ) ; glVertex3d (  0.61803398875, 0.0,  1.61803398875 ) ; glVertex3d ( -0.61803398875, 0.0,  1.61803398875 ) ; glVertex3d ( -1.0, -1.0,  1.0 ) ;
  784.   glEnd () ;
  785.   glBegin ( GL_LINE_LOOP ) ;
  786.   glNormal3d (  0.0, -0.525731112119, -0.850650808354 ) ; glVertex3d (  0.0, -1.61803398875, -0.61803398875 ) ; glVertex3d ( -1.0, -1.0, -1.0 ) ; glVertex3d ( -0.61803398875, 0.0, -1.61803398875 ) ; glVertex3d (  0.61803398875, 0.0, -1.61803398875 ) ; glVertex3d (  1.0, -1.0, -1.0 ) ;
  787.   glEnd () ;
  788.  
  789.   glBegin ( GL_LINE_LOOP ) ;
  790.   glNormal3d (  0.850650808354,  0.0,  0.525731112119 ) ; glVertex3d (  0.61803398875,  0.0,  1.61803398875 ) ; glVertex3d (  1.0, -1.0,  1.0 ) ; glVertex3d (  1.61803398875, -0.61803398875, 0.0 ) ; glVertex3d (  1.61803398875,  0.61803398875, 0.0 ) ; glVertex3d (  1.0,  1.0,  1.0 ) ;
  791.   glEnd () ;
  792.   glBegin ( GL_LINE_LOOP ) ;
  793.   glNormal3d ( -0.850650808354,  0.0,  0.525731112119 ) ; glVertex3d ( -0.61803398875,  0.0,  1.61803398875 ) ; glVertex3d ( -1.0,  1.0,  1.0 ) ; glVertex3d ( -1.61803398875,  0.61803398875, 0.0 ) ; glVertex3d ( -1.61803398875, -0.61803398875, 0.0 ) ; glVertex3d ( -1.0, -1.0,  1.0 ) ;
  794.   glEnd () ;
  795.   glBegin ( GL_LINE_LOOP ) ;
  796.   glNormal3d (  0.850650808354,  0.0, -0.525731112119 ) ; glVertex3d (  0.61803398875,  0.0, -1.61803398875 ) ; glVertex3d (  1.0,  1.0, -1.0 ) ; glVertex3d (  1.61803398875,  0.61803398875, 0.0 ) ; glVertex3d (  1.61803398875, -0.61803398875, 0.0 ) ; glVertex3d (  1.0, -1.0, -1.0 ) ;
  797.   glEnd () ;
  798.   glBegin ( GL_LINE_LOOP ) ;
  799.   glNormal3d ( -0.850650808354,  0.0, -0.525731112119 ) ; glVertex3d ( -0.61803398875,  0.0, -1.61803398875 ) ; glVertex3d ( -1.0, -1.0, -1.0 ) ; glVertex3d ( -1.61803398875, -0.61803398875, 0.0 ) ; glVertex3d ( -1.61803398875,  0.61803398875, 0.0 ) ; glVertex3d ( -1.0,  1.0, -1.0 ) ;
  800.   glEnd () ;
  801.  
  802.   glBegin ( GL_LINE_LOOP ) ;
  803.   glNormal3d (  0.525731112119,  0.850650808354,  0.0 ) ; glVertex3d (  1.61803398875,  0.61803398875,  0.0 ) ; glVertex3d (  1.0,  1.0, -1.0 ) ; glVertex3d ( 0.0,  1.61803398875, -0.61803398875 ) ; glVertex3d ( 0.0,  1.61803398875,  0.61803398875 ) ; glVertex3d (  1.0,  1.0,  1.0 ) ;
  804.   glEnd () ;
  805.   glBegin ( GL_LINE_LOOP ) ;
  806.   glNormal3d (  0.525731112119, -0.850650808354,  0.0 ) ; glVertex3d (  1.61803398875, -0.61803398875,  0.0 ) ; glVertex3d (  1.0, -1.0,  1.0 ) ; glVertex3d ( 0.0, -1.61803398875,  0.61803398875 ) ; glVertex3d ( 0.0, -1.61803398875, -0.61803398875 ) ; glVertex3d (  1.0, -1.0, -1.0 ) ;
  807.   glEnd () ;
  808.   glBegin ( GL_LINE_LOOP ) ;
  809.   glNormal3d ( -0.525731112119,  0.850650808354,  0.0 ) ; glVertex3d ( -1.61803398875,  0.61803398875,  0.0 ) ; glVertex3d ( -1.0,  1.0,  1.0 ) ; glVertex3d ( 0.0,  1.61803398875,  0.61803398875 ) ; glVertex3d ( 0.0,  1.61803398875, -0.61803398875 ) ; glVertex3d ( -1.0,  1.0, -1.0 ) ;
  810.   glEnd () ;
  811.   glBegin ( GL_LINE_LOOP ) ;
  812.   glNormal3d ( -0.525731112119, -0.850650808354,  0.0 ) ; glVertex3d ( -1.61803398875, -0.61803398875,  0.0 ) ; glVertex3d ( -1.0, -1.0, -1.0 ) ; glVertex3d ( 0.0, -1.61803398875, -0.61803398875 ) ; glVertex3d ( 0.0, -1.61803398875,  0.61803398875 ) ; glVertex3d ( -1.0, -1.0,  1.0 ) ;
  813.   glEnd () ;
  814. }
  815.  
  816. /*
  817.  *
  818.  */
  819. void FGAPIENTRY glutSolidDodecahedron( void )
  820. {
  821.   FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutSolidDodecahedron" );
  822.  
  823.   /* Magic Numbers:  It is possible to create a dodecahedron by attaching two pentagons to each face of
  824.    * of a cube.  The coordinates of the points are:
  825.    *   (+-x,0, z); (+-1, 1, 1); (0, z, x )
  826.    * where x = (-1 + sqrt(5))/2, z = (1 + sqrt(5))/2 or
  827.    *       x = 0.61803398875 and z = 1.61803398875.
  828.    */
  829.   glBegin ( GL_POLYGON ) ;
  830.   glNormal3d (  0.0,  0.525731112119,  0.850650808354 ) ; glVertex3d (  0.0,  1.61803398875,  0.61803398875 ) ; glVertex3d ( -1.0,  1.0,  1.0 ) ; glVertex3d ( -0.61803398875, 0.0,  1.61803398875 ) ; glVertex3d (  0.61803398875, 0.0,  1.61803398875 ) ; glVertex3d (  1.0,  1.0,  1.0 ) ;
  831.   glEnd () ;
  832.   glBegin ( GL_POLYGON ) ;
  833.   glNormal3d (  0.0,  0.525731112119, -0.850650808354 ) ; glVertex3d (  0.0,  1.61803398875, -0.61803398875 ) ; glVertex3d (  1.0,  1.0, -1.0 ) ; glVertex3d (  0.61803398875, 0.0, -1.61803398875 ) ; glVertex3d ( -0.61803398875, 0.0, -1.61803398875 ) ; glVertex3d ( -1.0,  1.0, -1.0 ) ;
  834.   glEnd () ;
  835.   glBegin ( GL_POLYGON ) ;
  836.   glNormal3d (  0.0, -0.525731112119,  0.850650808354 ) ; glVertex3d (  0.0, -1.61803398875,  0.61803398875 ) ; glVertex3d (  1.0, -1.0,  1.0 ) ; glVertex3d (  0.61803398875, 0.0,  1.61803398875 ) ; glVertex3d ( -0.61803398875, 0.0,  1.61803398875 ) ; glVertex3d ( -1.0, -1.0,  1.0 ) ;
  837.   glEnd () ;
  838.   glBegin ( GL_POLYGON ) ;
  839.   glNormal3d (  0.0, -0.525731112119, -0.850650808354 ) ; glVertex3d (  0.0, -1.61803398875, -0.61803398875 ) ; glVertex3d ( -1.0, -1.0, -1.0 ) ; glVertex3d ( -0.61803398875, 0.0, -1.61803398875 ) ; glVertex3d (  0.61803398875, 0.0, -1.61803398875 ) ; glVertex3d (  1.0, -1.0, -1.0 ) ;
  840.   glEnd () ;
  841.  
  842.   glBegin ( GL_POLYGON ) ;
  843.   glNormal3d (  0.850650808354,  0.0,  0.525731112119 ) ; glVertex3d (  0.61803398875,  0.0,  1.61803398875 ) ; glVertex3d (  1.0, -1.0,  1.0 ) ; glVertex3d (  1.61803398875, -0.61803398875, 0.0 ) ; glVertex3d (  1.61803398875,  0.61803398875, 0.0 ) ; glVertex3d (  1.0,  1.0,  1.0 ) ;
  844.   glEnd () ;
  845.   glBegin ( GL_POLYGON ) ;
  846.   glNormal3d ( -0.850650808354,  0.0,  0.525731112119 ) ; glVertex3d ( -0.61803398875,  0.0,  1.61803398875 ) ; glVertex3d ( -1.0,  1.0,  1.0 ) ; glVertex3d ( -1.61803398875,  0.61803398875, 0.0 ) ; glVertex3d ( -1.61803398875, -0.61803398875, 0.0 ) ; glVertex3d ( -1.0, -1.0,  1.0 ) ;
  847.   glEnd () ;
  848.   glBegin ( GL_POLYGON ) ;
  849.   glNormal3d (  0.850650808354,  0.0, -0.525731112119 ) ; glVertex3d (  0.61803398875,  0.0, -1.61803398875 ) ; glVertex3d (  1.0,  1.0, -1.0 ) ; glVertex3d (  1.61803398875,  0.61803398875, 0.0 ) ; glVertex3d (  1.61803398875, -0.61803398875, 0.0 ) ; glVertex3d (  1.0, -1.0, -1.0 ) ;
  850.   glEnd () ;
  851.   glBegin ( GL_POLYGON ) ;
  852.   glNormal3d ( -0.850650808354,  0.0, -0.525731112119 ) ; glVertex3d ( -0.61803398875,  0.0, -1.61803398875 ) ; glVertex3d ( -1.0, -1.0, -1.0 ) ; glVertex3d ( -1.61803398875, -0.61803398875, 0.0 ) ; glVertex3d ( -1.61803398875,  0.61803398875, 0.0 ) ; glVertex3d ( -1.0,  1.0, -1.0 ) ;
  853.   glEnd () ;
  854.  
  855.   glBegin ( GL_POLYGON ) ;
  856.   glNormal3d (  0.525731112119,  0.850650808354,  0.0 ) ; glVertex3d (  1.61803398875,  0.61803398875,  0.0 ) ; glVertex3d (  1.0,  1.0, -1.0 ) ; glVertex3d ( 0.0,  1.61803398875, -0.61803398875 ) ; glVertex3d ( 0.0,  1.61803398875,  0.61803398875 ) ; glVertex3d (  1.0,  1.0,  1.0 ) ;
  857.   glEnd () ;
  858.   glBegin ( GL_POLYGON ) ;
  859.   glNormal3d (  0.525731112119, -0.850650808354,  0.0 ) ; glVertex3d (  1.61803398875, -0.61803398875,  0.0 ) ; glVertex3d (  1.0, -1.0,  1.0 ) ; glVertex3d ( 0.0, -1.61803398875,  0.61803398875 ) ; glVertex3d ( 0.0, -1.61803398875, -0.61803398875 ) ; glVertex3d (  1.0, -1.0, -1.0 ) ;
  860.   glEnd () ;
  861.   glBegin ( GL_POLYGON ) ;
  862.   glNormal3d ( -0.525731112119,  0.850650808354,  0.0 ) ; glVertex3d ( -1.61803398875,  0.61803398875,  0.0 ) ; glVertex3d ( -1.0,  1.0,  1.0 ) ; glVertex3d ( 0.0,  1.61803398875,  0.61803398875 ) ; glVertex3d ( 0.0,  1.61803398875, -0.61803398875 ) ; glVertex3d ( -1.0,  1.0, -1.0 ) ;
  863.   glEnd () ;
  864.   glBegin ( GL_POLYGON ) ;
  865.   glNormal3d ( -0.525731112119, -0.850650808354,  0.0 ) ; glVertex3d ( -1.61803398875, -0.61803398875,  0.0 ) ; glVertex3d ( -1.0, -1.0, -1.0 ) ; glVertex3d ( 0.0, -1.61803398875, -0.61803398875 ) ; glVertex3d ( 0.0, -1.61803398875,  0.61803398875 ) ; glVertex3d ( -1.0, -1.0,  1.0 ) ;
  866.   glEnd () ;
  867. }
  868.  
  869. /*
  870.  *
  871.  */
  872. void FGAPIENTRY glutWireOctahedron( void )
  873. {
  874.   FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutWireOctahedron" );
  875.  
  876. #define RADIUS    1.0f
  877.   glBegin( GL_LINE_LOOP );
  878.     glNormal3d( 0.577350269189, 0.577350269189, 0.577350269189); glVertex3d( RADIUS, 0.0, 0.0 ); glVertex3d( 0.0, RADIUS, 0.0 ); glVertex3d( 0.0, 0.0, RADIUS );
  879.     glNormal3d( 0.577350269189, 0.577350269189,-0.577350269189); glVertex3d( RADIUS, 0.0, 0.0 ); glVertex3d( 0.0, 0.0,-RADIUS ); glVertex3d( 0.0, RADIUS, 0.0 );
  880.     glNormal3d( 0.577350269189,-0.577350269189, 0.577350269189); glVertex3d( RADIUS, 0.0, 0.0 ); glVertex3d( 0.0, 0.0, RADIUS ); glVertex3d( 0.0,-RADIUS, 0.0 );
  881.     glNormal3d( 0.577350269189,-0.577350269189,-0.577350269189); glVertex3d( RADIUS, 0.0, 0.0 ); glVertex3d( 0.0,-RADIUS, 0.0 ); glVertex3d( 0.0, 0.0,-RADIUS );
  882.     glNormal3d(-0.577350269189, 0.577350269189, 0.577350269189); glVertex3d(-RADIUS, 0.0, 0.0 ); glVertex3d( 0.0, 0.0, RADIUS ); glVertex3d( 0.0, RADIUS, 0.0 );
  883.     glNormal3d(-0.577350269189, 0.577350269189,-0.577350269189); glVertex3d(-RADIUS, 0.0, 0.0 ); glVertex3d( 0.0, RADIUS, 0.0 ); glVertex3d( 0.0, 0.0,-RADIUS );
  884.     glNormal3d(-0.577350269189,-0.577350269189, 0.577350269189); glVertex3d(-RADIUS, 0.0, 0.0 ); glVertex3d( 0.0,-RADIUS, 0.0 ); glVertex3d( 0.0, 0.0, RADIUS );
  885.     glNormal3d(-0.577350269189,-0.577350269189,-0.577350269189); glVertex3d(-RADIUS, 0.0, 0.0 ); glVertex3d( 0.0, 0.0,-RADIUS ); glVertex3d( 0.0,-RADIUS, 0.0 );
  886.   glEnd();
  887. #undef RADIUS
  888. }
  889.  
  890. /*
  891.  *
  892.  */
  893. void FGAPIENTRY glutSolidOctahedron( void )
  894. {
  895.   FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutSolidOctahedron" );
  896.  
  897. #define RADIUS    1.0f
  898.   glBegin( GL_TRIANGLES );
  899.     glNormal3d( 0.577350269189, 0.577350269189, 0.577350269189); glVertex3d( RADIUS, 0.0, 0.0 ); glVertex3d( 0.0, RADIUS, 0.0 ); glVertex3d( 0.0, 0.0, RADIUS );
  900.     glNormal3d( 0.577350269189, 0.577350269189,-0.577350269189); glVertex3d( RADIUS, 0.0, 0.0 ); glVertex3d( 0.0, 0.0,-RADIUS ); glVertex3d( 0.0, RADIUS, 0.0 );
  901.     glNormal3d( 0.577350269189,-0.577350269189, 0.577350269189); glVertex3d( RADIUS, 0.0, 0.0 ); glVertex3d( 0.0, 0.0, RADIUS ); glVertex3d( 0.0,-RADIUS, 0.0 );
  902.     glNormal3d( 0.577350269189,-0.577350269189,-0.577350269189); glVertex3d( RADIUS, 0.0, 0.0 ); glVertex3d( 0.0,-RADIUS, 0.0 ); glVertex3d( 0.0, 0.0,-RADIUS );
  903.     glNormal3d(-0.577350269189, 0.577350269189, 0.577350269189); glVertex3d(-RADIUS, 0.0, 0.0 ); glVertex3d( 0.0, 0.0, RADIUS ); glVertex3d( 0.0, RADIUS, 0.0 );
  904.     glNormal3d(-0.577350269189, 0.577350269189,-0.577350269189); glVertex3d(-RADIUS, 0.0, 0.0 ); glVertex3d( 0.0, RADIUS, 0.0 ); glVertex3d( 0.0, 0.0,-RADIUS );
  905.     glNormal3d(-0.577350269189,-0.577350269189, 0.577350269189); glVertex3d(-RADIUS, 0.0, 0.0 ); glVertex3d( 0.0,-RADIUS, 0.0 ); glVertex3d( 0.0, 0.0, RADIUS );
  906.     glNormal3d(-0.577350269189,-0.577350269189,-0.577350269189); glVertex3d(-RADIUS, 0.0, 0.0 ); glVertex3d( 0.0, 0.0,-RADIUS ); glVertex3d( 0.0,-RADIUS, 0.0 );
  907.   glEnd();
  908. #undef RADIUS
  909. }
  910.  
  911. /* Magic Numbers:  r0 = ( 1, 0, 0 )
  912.  *                 r1 = ( -1/3, 2 sqrt(2) / 3, 0 )
  913.  *                 r2 = ( -1/3, -sqrt(2) / 3, sqrt(6) / 3 )
  914.  *                 r3 = ( -1/3, -sqrt(2) / 3, -sqrt(6) / 3 )
  915.  * |r0| = |r1| = |r2| = |r3| = 1
  916.  * Distance between any two points is 2 sqrt(6) / 3
  917.  *
  918.  * Normals:  The unit normals are simply the negative of the coordinates of the point not on the surface.
  919.  */
  920.  
  921. #define NUM_TETR_FACES     4
  922.  
  923. static GLdouble tet_r[4][3] = { {             1.0,             0.0,             0.0 },
  924.                                 { -0.333333333333,  0.942809041582,             0.0 },
  925.                                 { -0.333333333333, -0.471404520791,  0.816496580928 },
  926.                                 { -0.333333333333, -0.471404520791, -0.816496580928 } } ;
  927.  
  928. static GLint tet_i[4][3] =  /* Vertex indices */
  929. {
  930.   { 1, 3, 2 }, { 0, 2, 3 }, { 0, 3, 1 }, { 0, 1, 2 }
  931. } ;
  932.  
  933. /*
  934.  *
  935.  */
  936. void FGAPIENTRY glutWireTetrahedron( void )
  937. {
  938.   FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutWireTetrahedron" );
  939.  
  940.   glBegin( GL_LINE_LOOP ) ;
  941.     glNormal3d ( -tet_r[0][0], -tet_r[0][1], -tet_r[0][2] ) ; glVertex3dv ( tet_r[1] ) ; glVertex3dv ( tet_r[3] ) ; glVertex3dv ( tet_r[2] ) ;
  942.     glNormal3d ( -tet_r[1][0], -tet_r[1][1], -tet_r[1][2] ) ; glVertex3dv ( tet_r[0] ) ; glVertex3dv ( tet_r[2] ) ; glVertex3dv ( tet_r[3] ) ;
  943.     glNormal3d ( -tet_r[2][0], -tet_r[2][1], -tet_r[2][2] ) ; glVertex3dv ( tet_r[0] ) ; glVertex3dv ( tet_r[3] ) ; glVertex3dv ( tet_r[1] ) ;
  944.     glNormal3d ( -tet_r[3][0], -tet_r[3][1], -tet_r[3][2] ) ; glVertex3dv ( tet_r[0] ) ; glVertex3dv ( tet_r[1] ) ; glVertex3dv ( tet_r[2] ) ;
  945.   glEnd() ;
  946. }
  947.  
  948. /*
  949.  *
  950.  */
  951. void FGAPIENTRY glutSolidTetrahedron( void )
  952. {
  953.   FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutSolidTetrahedron" );
  954.  
  955.   glBegin( GL_TRIANGLES ) ;
  956.     glNormal3d ( -tet_r[0][0], -tet_r[0][1], -tet_r[0][2] ) ; glVertex3dv ( tet_r[1] ) ; glVertex3dv ( tet_r[3] ) ; glVertex3dv ( tet_r[2] ) ;
  957.     glNormal3d ( -tet_r[1][0], -tet_r[1][1], -tet_r[1][2] ) ; glVertex3dv ( tet_r[0] ) ; glVertex3dv ( tet_r[2] ) ; glVertex3dv ( tet_r[3] ) ;
  958.     glNormal3d ( -tet_r[2][0], -tet_r[2][1], -tet_r[2][2] ) ; glVertex3dv ( tet_r[0] ) ; glVertex3dv ( tet_r[3] ) ; glVertex3dv ( tet_r[1] ) ;
  959.     glNormal3d ( -tet_r[3][0], -tet_r[3][1], -tet_r[3][2] ) ; glVertex3dv ( tet_r[0] ) ; glVertex3dv ( tet_r[1] ) ; glVertex3dv ( tet_r[2] ) ;
  960.   glEnd() ;
  961. }
  962.  
  963. /*
  964.  *
  965.  */
  966. static double icos_r[12][3] = {
  967.     {  1.0,             0.0,             0.0            },
  968.     {  0.447213595500,  0.894427191000,  0.0            },
  969.     {  0.447213595500,  0.276393202252,  0.850650808354 },
  970.     {  0.447213595500, -0.723606797748,  0.525731112119 },
  971.     {  0.447213595500, -0.723606797748, -0.525731112119 },
  972.     {  0.447213595500,  0.276393202252, -0.850650808354 },
  973.     { -0.447213595500, -0.894427191000,  0.0 },
  974.     { -0.447213595500, -0.276393202252,  0.850650808354 },
  975.     { -0.447213595500,  0.723606797748,  0.525731112119 },
  976.     { -0.447213595500,  0.723606797748, -0.525731112119 },
  977.     { -0.447213595500, -0.276393202252, -0.850650808354 },
  978.     { -1.0,             0.0,             0.0            }
  979. };
  980.  
  981. static int icos_v [20][3] = {
  982.     {  0,  1,  2 },
  983.     {  0,  2,  3 },
  984.     {  0,  3,  4 },
  985.     {  0,  4,  5 },
  986.     {  0,  5,  1 },
  987.     {  1,  8,  2 },
  988.     {  2,  7,  3 },
  989.     {  3,  6,  4 },
  990.     {  4, 10,  5 },
  991.     {  5,  9,  1 },
  992.     {  1,  9,  8 },
  993.     {  2,  8,  7 },
  994.     {  3,  7,  6 },
  995.     {  4,  6, 10 },
  996.     {  5, 10,  9 },
  997.     { 11,  9, 10 },
  998.     { 11,  8,  9 },
  999.     { 11,  7,  8 },
  1000.     { 11,  6,  7 },
  1001.     { 11, 10,  6 }
  1002. };
  1003.  
  1004. void FGAPIENTRY glutWireIcosahedron( void )
  1005. {
  1006.   int i ;
  1007.  
  1008.   FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutWireIcosahedron" );
  1009.  
  1010.   for ( i = 0; i < 20; i++ )
  1011.   {
  1012.     double normal[3] ;
  1013.     normal[0] = ( icos_r[icos_v[i][1]][1] - icos_r[icos_v[i][0]][1] ) * ( icos_r[icos_v[i][2]][2] - icos_r[icos_v[i][0]][2] ) - ( icos_r[icos_v[i][1]][2] - icos_r[icos_v[i][0]][2] ) * ( icos_r[icos_v[i][2]][1] - icos_r[icos_v[i][0]][1] ) ;
  1014.     normal[1] = ( icos_r[icos_v[i][1]][2] - icos_r[icos_v[i][0]][2] ) * ( icos_r[icos_v[i][2]][0] - icos_r[icos_v[i][0]][0] ) - ( icos_r[icos_v[i][1]][0] - icos_r[icos_v[i][0]][0] ) * ( icos_r[icos_v[i][2]][2] - icos_r[icos_v[i][0]][2] ) ;
  1015.     normal[2] = ( icos_r[icos_v[i][1]][0] - icos_r[icos_v[i][0]][0] ) * ( icos_r[icos_v[i][2]][1] - icos_r[icos_v[i][0]][1] ) - ( icos_r[icos_v[i][1]][1] - icos_r[icos_v[i][0]][1] ) * ( icos_r[icos_v[i][2]][0] - icos_r[icos_v[i][0]][0] ) ;
  1016.     glBegin ( GL_LINE_LOOP ) ;
  1017.       glNormal3dv ( normal ) ;
  1018.       glVertex3dv ( icos_r[icos_v[i][0]] ) ;
  1019.       glVertex3dv ( icos_r[icos_v[i][1]] ) ;
  1020.       glVertex3dv ( icos_r[icos_v[i][2]] ) ;
  1021.     glEnd () ;
  1022.   }
  1023. }
  1024.  
  1025. /*
  1026.  *
  1027.  */
  1028. void FGAPIENTRY glutSolidIcosahedron( void )
  1029. {
  1030.   int i ;
  1031.  
  1032.   FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutSolidIcosahedron" );
  1033.  
  1034.   glBegin ( GL_TRIANGLES ) ;
  1035.   for ( i = 0; i < 20; i++ )
  1036.   {
  1037.     double normal[3] ;
  1038.     normal[0] = ( icos_r[icos_v[i][1]][1] - icos_r[icos_v[i][0]][1] ) * ( icos_r[icos_v[i][2]][2] - icos_r[icos_v[i][0]][2] ) - ( icos_r[icos_v[i][1]][2] - icos_r[icos_v[i][0]][2] ) * ( icos_r[icos_v[i][2]][1] - icos_r[icos_v[i][0]][1] ) ;
  1039.     normal[1] = ( icos_r[icos_v[i][1]][2] - icos_r[icos_v[i][0]][2] ) * ( icos_r[icos_v[i][2]][0] - icos_r[icos_v[i][0]][0] ) - ( icos_r[icos_v[i][1]][0] - icos_r[icos_v[i][0]][0] ) * ( icos_r[icos_v[i][2]][2] - icos_r[icos_v[i][0]][2] ) ;
  1040.     normal[2] = ( icos_r[icos_v[i][1]][0] - icos_r[icos_v[i][0]][0] ) * ( icos_r[icos_v[i][2]][1] - icos_r[icos_v[i][0]][1] ) - ( icos_r[icos_v[i][1]][1] - icos_r[icos_v[i][0]][1] ) * ( icos_r[icos_v[i][2]][0] - icos_r[icos_v[i][0]][0] ) ;
  1041.       glNormal3dv ( normal ) ;
  1042.       glVertex3dv ( icos_r[icos_v[i][0]] ) ;
  1043.       glVertex3dv ( icos_r[icos_v[i][1]] ) ;
  1044.       glVertex3dv ( icos_r[icos_v[i][2]] ) ;
  1045.   }
  1046.  
  1047.   glEnd () ;
  1048. }
  1049.  
  1050. /*
  1051.  *
  1052.  */
  1053. static double rdod_r[14][3] = {
  1054.     {  0.0,             0.0,             1.0 },
  1055.     {  0.707106781187,  0.000000000000,  0.5 },
  1056.     {  0.000000000000,  0.707106781187,  0.5 },
  1057.     { -0.707106781187,  0.000000000000,  0.5 },
  1058.     {  0.000000000000, -0.707106781187,  0.5 },
  1059.     {  0.707106781187,  0.707106781187,  0.0 },
  1060.     { -0.707106781187,  0.707106781187,  0.0 },
  1061.     { -0.707106781187, -0.707106781187,  0.0 },
  1062.     {  0.707106781187, -0.707106781187,  0.0 },
  1063.     {  0.707106781187,  0.000000000000, -0.5 },
  1064.     {  0.000000000000,  0.707106781187, -0.5 },
  1065.     { -0.707106781187,  0.000000000000, -0.5 },
  1066.     {  0.000000000000, -0.707106781187, -0.5 },
  1067.     {  0.0,             0.0,            -1.0 }
  1068. } ;
  1069.  
  1070. static int rdod_v [12][4] = {
  1071.     { 0,  1,  5,  2 },
  1072.     { 0,  2,  6,  3 },
  1073.     { 0,  3,  7,  4 },
  1074.     { 0,  4,  8,  1 },
  1075.     { 5, 10,  6,  2 },
  1076.     { 6, 11,  7,  3 },
  1077.     { 7, 12,  8,  4 },
  1078.     { 8,  9,  5,  1 },
  1079.     { 5,  9, 13, 10 },
  1080.     { 6, 10, 13, 11 },
  1081.     { 7, 11, 13, 12 },
  1082.     { 8, 12, 13,  9 }
  1083. };
  1084.  
  1085. static double rdod_n[12][3] = {
  1086.     {  0.353553390594,  0.353553390594,  0.5 },
  1087.     { -0.353553390594,  0.353553390594,  0.5 },
  1088.     { -0.353553390594, -0.353553390594,  0.5 },
  1089.     {  0.353553390594, -0.353553390594,  0.5 },
  1090.     {  0.000000000000,  1.000000000000,  0.0 },
  1091.     { -1.000000000000,  0.000000000000,  0.0 },
  1092.     {  0.000000000000, -1.000000000000,  0.0 },
  1093.     {  1.000000000000,  0.000000000000,  0.0 },
  1094.     {  0.353553390594,  0.353553390594, -0.5 },
  1095.     { -0.353553390594,  0.353553390594, -0.5 },
  1096.     { -0.353553390594, -0.353553390594, -0.5 },
  1097.     {  0.353553390594, -0.353553390594, -0.5 }
  1098. };
  1099.  
  1100. void FGAPIENTRY glutWireRhombicDodecahedron( void )
  1101. {
  1102.   int i ;
  1103.  
  1104.   FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutWireRhombicDodecahedron" );
  1105.  
  1106.   for ( i = 0; i < 12; i++ )
  1107.   {
  1108.     glBegin ( GL_LINE_LOOP ) ;
  1109.       glNormal3dv ( rdod_n[i] ) ;
  1110.       glVertex3dv ( rdod_r[rdod_v[i][0]] ) ;
  1111.       glVertex3dv ( rdod_r[rdod_v[i][1]] ) ;
  1112.       glVertex3dv ( rdod_r[rdod_v[i][2]] ) ;
  1113.       glVertex3dv ( rdod_r[rdod_v[i][3]] ) ;
  1114.     glEnd () ;
  1115.   }
  1116. }
  1117.  
  1118. /*
  1119.  *
  1120.  */
  1121. void FGAPIENTRY glutSolidRhombicDodecahedron( void )
  1122. {
  1123.   int i ;
  1124.  
  1125.   FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutSolidRhombicDodecahedron" );
  1126.  
  1127.   glBegin ( GL_QUADS ) ;
  1128.   for ( i = 0; i < 12; i++ )
  1129.   {
  1130.       glNormal3dv ( rdod_n[i] ) ;
  1131.       glVertex3dv ( rdod_r[rdod_v[i][0]] ) ;
  1132.       glVertex3dv ( rdod_r[rdod_v[i][1]] ) ;
  1133.       glVertex3dv ( rdod_r[rdod_v[i][2]] ) ;
  1134.       glVertex3dv ( rdod_r[rdod_v[i][3]] ) ;
  1135.   }
  1136.  
  1137.   glEnd () ;
  1138. }
  1139.  
  1140. void FGAPIENTRY glutWireSierpinskiSponge ( int num_levels, GLdouble offset[3], GLdouble scale )
  1141. {
  1142.   int i, j ;
  1143.  
  1144.   FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutWireSierpinskiSponge" );
  1145.  
  1146.   if ( num_levels == 0 )
  1147.   {
  1148.  
  1149.     for ( i = 0 ; i < NUM_TETR_FACES ; i++ )
  1150.     {
  1151.       glBegin ( GL_LINE_LOOP ) ;
  1152.       glNormal3d ( -tet_r[i][0], -tet_r[i][1], -tet_r[i][2] ) ;
  1153.       for ( j = 0; j < 3; j++ )
  1154.       {
  1155.         double x = offset[0] + scale * tet_r[tet_i[i][j]][0] ;
  1156.         double y = offset[1] + scale * tet_r[tet_i[i][j]][1] ;
  1157.         double z = offset[2] + scale * tet_r[tet_i[i][j]][2] ;
  1158.         glVertex3d ( x, y, z ) ;
  1159.       }
  1160.  
  1161.       glEnd () ;
  1162.     }
  1163.   }
  1164.   else if ( num_levels > 0 )
  1165.   {
  1166.     GLdouble local_offset[3] ;  /* Use a local variable to avoid buildup of roundoff errors */
  1167.     num_levels -- ;
  1168.     scale /= 2.0 ;
  1169.     for ( i = 0 ; i < NUM_TETR_FACES ; i++ )
  1170.     {
  1171.       local_offset[0] = offset[0] + scale * tet_r[i][0] ;
  1172.       local_offset[1] = offset[1] + scale * tet_r[i][1] ;
  1173.       local_offset[2] = offset[2] + scale * tet_r[i][2] ;
  1174.       glutWireSierpinskiSponge ( num_levels, local_offset, scale ) ;
  1175.     }
  1176.   }
  1177. }
  1178.  
  1179. void FGAPIENTRY glutSolidSierpinskiSponge ( int num_levels, GLdouble offset[3], GLdouble scale )
  1180. {
  1181.   int i, j ;
  1182.  
  1183.   FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutSolidSierpinskiSponge" );
  1184.  
  1185.   if ( num_levels == 0 )
  1186.   {
  1187.     glBegin ( GL_TRIANGLES ) ;
  1188.  
  1189.     for ( i = 0 ; i < NUM_TETR_FACES ; i++ )
  1190.     {
  1191.       glNormal3d ( -tet_r[i][0], -tet_r[i][1], -tet_r[i][2] ) ;
  1192.       for ( j = 0; j < 3; j++ )
  1193.       {
  1194.         double x = offset[0] + scale * tet_r[tet_i[i][j]][0] ;
  1195.         double y = offset[1] + scale * tet_r[tet_i[i][j]][1] ;
  1196.         double z = offset[2] + scale * tet_r[tet_i[i][j]][2] ;
  1197.         glVertex3d ( x, y, z ) ;
  1198.       }
  1199.     }
  1200.  
  1201.     glEnd () ;
  1202.   }
  1203.   else if ( num_levels > 0 )
  1204.   {
  1205.     GLdouble local_offset[3] ;  /* Use a local variable to avoid buildup of roundoff errors */
  1206.     num_levels -- ;
  1207.     scale /= 2.0 ;
  1208.     for ( i = 0 ; i < NUM_TETR_FACES ; i++ )
  1209.     {
  1210.       local_offset[0] = offset[0] + scale * tet_r[i][0] ;
  1211.       local_offset[1] = offset[1] + scale * tet_r[i][1] ;
  1212.       local_offset[2] = offset[2] + scale * tet_r[i][2] ;
  1213.       glutSolidSierpinskiSponge ( num_levels, local_offset, scale ) ;
  1214.     }
  1215.   }
  1216. }
  1217.  
  1218. /*** END OF FILE ***/
  1219.  
« Last Edit: March 08, 2019, 02:25:47 pm by Craz1000 »

Offline Craz1000

  • Forum Regular
  • Posts: 111
  • I'm OK
    • View Profile
    • Craz1000.net
Re: GL Sphere
« Reply #8 on: March 08, 2019, 03:10:40 pm »
Got it, had to purge precompiled files