# 31. OpenGL Sphere Creation

Fancy… Here we are going to create our own sphere without the use of

GLUT. I chose to write this tutorial, because I did not like the way

you could and could not texture the sphere created by GLUT and when

I looked on the internet, I could not find any tutorials on it. The advantage

of our sphere, is that we can set texture coordinates and if need be, place it

inside either a display list, vertex array, or vertex buffer object, allowing

us to call alot more than in immediate mode.

———————————————————————

Section 1: Variables

Now to start off, here are the variables we are going to be using:

This will hold our texture

**GLuint texture[1];**

This will just hold our angle of rotation

**double angle = 0;**

This here will hold the information of all our vertices, such as

x, y and z coordinates along with texture coordinates.

**typedef struct
{**

The x position of our current vertex

**int X;**

The Y position of our current vertex

**int Y;**

The Z position of our current vertex

**int Z;**

The U(x) texture coordinate of the current vertex

**double U;**

The V(x) texture coordinate of the current vertex

**double V;
}VERTICES;**

Next we are going to use PI to convert our angles in degrees to radians.

**const double PI = 3.1415926535897;**

This here is going to determine how far apart each of our vertices are

the further apart, the faster the program, but the squarer the sphere.

I chose 10 because it looks nice, and runs excellent.

**const space = 10;**

This will hold out total amount of vertices.

**const VertexCount = (90 / space) * (360 / space) * 4;**

Now we set up how many vertices we are going to use.

**VERTICES VERTEX[VertexCount];**

———————————————————————

Section 2: Enabling and Creating

Here I am enabling depth testing, texturing and face culling. The depth testing

is so that we acctually have depth to our scene, the texturing is so that

we can apply textures to our sphere, and culling to used to speed up the

application. I have set the front face for culling to Counter Clock Wise, as triangle

strips cull the opposite face to most other shapes.

**glEnable(GL_DEPTH_TEST);
glEnable( GL_TEXTURE_2D );
glDepthFunc(GL_LEQUAL);
glCullFace(GL_BACK);
glFrontFace(GL_CCW);
glEnable(GL_CULL_FACE);**

Now we load our texture to be used. It will be stored in texture[0]

**texture[0] = LoadTextureRAW( “texture.raw” );**

Now we call to create the sphere, I do not know why it does this, but the first

input seems to choose how many subdivisions to perform. The next lets you choose

where to move the sphere on the x, y and z axis.

**CreateSphere(70,0,0,0);**

Now for the actual creation code. We are inputting R as the number of subdivisions,

H as the translation on the horizontal axis, K as the translation on the vertical

axis, and Z as the translation on the Z axis.

**void CreateSphere (double R, double H, double K, double Z) {**

Now are variables for this is as followed. n is the current vertex we are working

with. While a and b are used to control our loops.

**int n;
double a;
double b;**

Set n to 0 to start off with the first vertex

**n = 0;**

Assign our b loop to go through 90 degrees in intervals of our variable space

**for( b = 0; b <= 90 – space; b+=space){**

Assign our a loop to go through 360 degrees in intervals of our variable space

**for( a = 0; a <= 360 – space; a+=space){**

Start editing our vertex.

I am calculating the X value here.

**VERTEX[n].X = R * sin((a) / 180 * PI) * sin((b) / 180 * PI) – H;**

The Y value here.

**VERTEX[n].Y = R * cos((a) / 180 * PI) * sin((b) / 180 * PI) + K;**

The Z value here.

**VERTEX[n].Z = R * cos((b) / 180 * PI) – Z;**

Now I am calculating the texture coordinates. I have used (2*b) as the texture

is twice as wide as it is high. Hence 2:1. You can remove the (2*) if you wish

to use a texture with the same width and height, or increase it accordingly.

**VERTEX[n].V = (2 * b) / 360;
VERTEX[n].U = (a) / 360;**

Then start working with the next vertex

**n++;**

Then we do the same calculations as before, only adding the space variable

to the b values.

**VERTEX[n].X = R * sin((a) / 180 * PI) * sin((b + space) / 180 * PI) – H;
VERTEX[n].Y = R * cos((a) / 180 * PI) * sin((b + space) / 180 * PI) + K;
VERTEX[n].Z = R * cos((b + space) / 180 * PI) – Z;
VERTEX[n].V = (2 * (b + space)) / 360;
VERTEX[n].U = (a) / 360;
n++;**

Then we do the same calculations as the first, only adding the space variable

to the a values.

**VERTEX[n].X = R * sin((a + space) / 180 * PI) * sin((b) / 180 * PI) – H;
VERTEX[n].Y = R * cos((a + space) / 180 * PI) * sin((b) / 180 * PI) + K;
VERTEX[n].Z = R * cos((b) / 180 * PI) – Z;
VERTEX[n].V = (2 * b) / 360;
VERTEX[n].U = (a + space) / 360;
n++;**

Then we do the same calculations as the first again, only adding the space variable

to both the b and the a values.

**VERTEX[n].X = R * sin((a + space) / 180 * PI) * sin((b + space) / 180 * PI) – H;
VERTEX[n].Y = R * cos((a + space) / 180 * PI) * sin((b + space) / 180 * PI) + K;
VERTEX[n].Z = R * cos((b + space) / 180 * PI) – Z;
VERTEX[n].V = (2 * (b + space)) / 360;
VERTEX[n].U = (a + space) / 360;
n++;**

**}
}
}**

———————————————————————————

Section 3: Displaying the Sphere

To display the sphere I am calling this funtion which will set the size of it

to 5 and assign the texture specified.

**DisplaySphere(5, texture[0]);**

This is the actual displaying code itself, it inputs the radius and texture

**void DisplaySphere (double R, GLuint texture){**

This variable will control which vertex we are currently working with

**int b;**

I have chosen to scale it here to 0.0125 times its original size, and then

increase it by R as the original sphere is rather large.

**glScalef (0.0125 * R, 0.0125 * R, 0.0125 * R);**

Now I am rotating it because, if you run it, it is sideways

**glRotatef (90, 1, 0, 0);**

Now I bind the texure we inputted above.

**glBindTexture (GL_TEXTURE_2D, texture);**

Now to begin drawing the sphere itself. I am drawing it with triangle strips

as they are the fastest shape for this.

**glBegin (GL_TRIANGLE_STRIP);**

Now I am looping through each vertex

**for ( b = 0; b <= VertexCount; b++){**

Assigning the texture coordinates of the current vertex

**glTexCoord2f (VERTEX[b].U, VERTEX[b].V);**

And the drawing the specified vertex with the Z coordinate inverted. Because

our creation code only draws half a sphere, which is why I am also doing

this loop again for the other half below.

**glVertex3f (VERTEX[b].X, VERTEX[b].Y, -VERTEX[b].Z);
}**

And here I do the same as above, only this time, I invert

the V(y) texture coordinate.

**for ( b = 0; b <= VertexCount; b++){
glTexCoord2f (VERTEX[b].U, -VERTEX[b].V);
glVertex3f (VERTEX[b].X, VERTEX[b].Y, VERTEX[b].Z);
}**

Then end the shape.

**glEnd();**

}

}

———————————————————————————

And there we have it. A textured sphere without the need for GLUT

If you have any questions, please email me at swiftless@gmail.com

1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. 55. 56. 57. 58. 59. 60. 61. 62. 63. 64. 65. 66. 67. 68. 69. 70. 71. 72. 73. 74. 75. 76. 77. 78. 79. 80. 81. 82. 83. 84. 85. 86. 87. 88. 89. 90. 91. 92. 93. 94. 95. 96. 97. 98. 99. 100. 101. 102. 103. 104. 105. 106. 107. 108. 109. 110. 111. 112. 113. 114. 115. 116. 117. 118. 119. 120. 121. 122. 123. 124. 125. 126. 127. 128. 129. 130. 131. 132. 133. 134. 135. 136. 137. 138. 139. 140. 141. 142. 143. 144. 145. 146. 147. 148. 149. 150. 151. 152. 153. 154. 155. 156. 157. 158. 159. 160. 161. 162. 163. 164. 165. 166. 167. 168. 169. 170. 171. 172. 173. 174. 175. 176. 177. 178. 179. 180. 181. 182. 183. 184. 185. 186. 187. 188. 189. 190. 191. 192. |
#include <GL/gl.h> #include <GL/glut.h> #include <windows.h> #include <stdio.h> #include <math.h> #include <iostream.h> GLuint texture[1]; double angle = 0; typedef struct const double PI = 3.1415926535897; const space = 10; const VertexCount = (90 / space) * (360 / space) * 4; VERTICES VERTEX[VertexCount]; GLuint LoadTextureRAW( const char * filename ); void DisplaySphere (double R, GLuint texture){ void CreateSphere (double R, double H, double K, double Z) { void display (void) { void init (void) { int main (int argc, char **argv) { GLuint LoadTextureRAW( const char * filename ) |

Download Sphere Texture(.RAW file)

Download Sphere Texture(.BMP file)