# OpenGL calculate UV sphere vertices

I am trying to implement a class Sphere in C++.

Therefore I want to calculate the vertices in the constructor of the class (or in a seperate function..). Although I read tons of articles about creating spheres in different ways (UV Sphere, Quad Sphere, Icosphere etc.) I did not understand how to create the vertices for my buffer object.

I decided to use the UV Sphere since it is easy to map a texture on it.

A "UV sphere" in this sense is one where the (quad) edges run like lines of latitude and longitude, and the texture is mapped to the sphere like an equirectangular projection.

But how can I calculate all the vertex positions and texture coordinates?

For my vertices I use a Vertex struct:

struct Vertex
{
glm::vec3 position;
glm::vec2 texture;
};

• It can be tempting to compute this sort of stuff on the fly, but honestly, it's easier to just download a texture mapped obj model for a sphere. That way you spend less time on unnecessary algorithms and more on actually making games. – Ian Young Nov 1 '17 at 9:20

Let's start by generating all unique vertices. You can then decide whether to index those vertices, or copy them into strips/fans, depending on your needs.

// One vertex at every latitude-longitude intersection,
// plus one for the north pole and one for the south.
// One meridian serves as a UV seam, so we double the vertices there.
int numVertices = numLatitudeLines * (numLongitudeLines + 1) + 2

vec3[] positions = vec3[numVertices]
vec2[] texcoords = vec2[numVertices]

// North pole.
texcoords[0] = vec2(0, 1)

// South pole.
positions[numVertices - 1] = vec3(0, -radius, 0)
texcoords[numVertices - 1] = vec2(0, 0)

// +1.0f because there's a gap between the poles and the first parallel.
float latitudeSpacing = 1.0f / (numLatitudeLines + 1.0f)
float longitudeSpacing = 1.0f / (numLongitudeLines)

// start writing new vertices at position 1
int v = 1
for(latitude = 0; latitude < numLatitudeLines; latitude++) {
for(longitude = 0; longitude <= numLongitudeLines; longitude++) {

// Scale coordinates into the 0...1 texture coordinate range,
// with north at the top (y = 1).
texcoords[v] = vec2(
longitude * longitudeSpacing,
1.0f - (latitude + 1) * latitudeSpacing
)

// Convert to spherical coordinates:
// theta is a longitude angle (around the equator) in radians.
// phi is a latitude angle (north or south of the equator).
float theta = texcoords[v].x * 2.0f * PI
float phi = (texcoords[v].y - 0.5f) * PI

// This determines the radius of the ring of this line of latitude.
// It's widest at the equator, and narrows as phi increases/decreases.
float c = cos(phi)

// Usual formula for a vector in spherical coordinates.
// You can exchange x & z to wind the opposite way around the sphere.
positions[v] = vec3(
c * cos(theta),
sin(phi),
c * sin(theta)