I want to draw a sphere using VBO for vertex, color and UV coordinates for texture. My problem is that the sphere is not 'closed', there is a hole in the origin. I know that this is because my code depends on (1/segments) distance between each vertex; I am working with segments = 40. I know that, if I rise that value, the hole will be lower, but program is slower. I don't know if there's a way to eliminate the hole without rise the variable.
Here's the code:
for(int i = 0; i <= segments; i++){
double lat0 = pi * (-0.5 + (double)(i - 1) / segments);
double z0 = sin(lat0);
double zr0 = cos(lat0);
// lat1 = [-pi/2..pi/2]
double lat1 = pi * (-0.5 + (double)i / segments);
double z1 = sin(lat1);
double zr1 = cos(lat1);
for (int j = 0; j <= segments; j++){ // Longitud
// lng = [0..2*pi]
double lng = 2 * pi * (double)(j - 1) / segments;
double x = cos(lng);
double y = sin(lng);
//glNormal3f(x * zr0, y * zr0, z0); // Normals
ballVerts.push_back(x * zr0); //X
ballVerts.push_back(y * zr0); //Y
ballVerts.push_back(z0); //Z
ballVerts.push_back(0.0f);
ballVerts.push_back(0.0f);
ballVerts.push_back(0.0f);
ballVerts.push_back(1.0f); //R,G,B,A
texX = abs(1 - (0.5f + atan2(z0, x * zr0) / (2.0 * pi)));
texY = 0.5f - asin(y * zr0) / pi;
ballVerts.push_back(texX); // Texture coords
ballVerts.push_back(texY); // U, V
//glNormal3f(x * zr1, y * zr1, z1); //Normals
ballVerts.push_back(x * zr1); //X
ballVerts.push_back(y * zr1); //Y
ballVerts.push_back(z1); //Z
ballVerts.push_back(0.0f);
ballVerts.push_back(0.0f);
ballVerts.push_back(1.0f);
ballVerts.push_back(1.0f); //R,G,B,A
texX = abs(1 - (0.5f + atan2(z1, x * zr1) / (2.0 * pi)));
texY = 0.5f - asin(y * zr1) / pi;
ballVerts.push_back(texX); // Texture coords
ballVerts.push_back(texY);
}
}
// Create VBO....
And this is the output I have:
I don't think that's a hole. You're drawing one segment too many, and causing it to draw additional triangles at the south pole, with the texture wrapped around:
In the first loop iteration, with
i = 0
, the angle will be less than-0.5 * pi
, resulting in the extra triangles shown in your picture.If you want to split the latitude range into
segments
pieces, you only need to run through the outer loopsegments
times. With the code above, with the loop from0
up to and includingsegments
, you're iteratingsegments + 1
times.The easiest way to fix this is to start the loop at
1
:I would probably loop from 0 and make the end exclusive, and change the angle calculations. But that's really equivalent: