0
\$\begingroup\$

I'm trying to generate points for a sphere by subdividing the space of spherical coordinate in res sector and res slices.

At first I did my own implementation, but it wasn't working. After a while I looked online and I copied Songho implementation and others as well.

But I still have the same issue: strip made of points

The points are not evenly spaced in the sphere, creating a strip.

This is the code I'm using to generate the sphere:

   float sectorStep = 2 * PI / res;
    float stackStep = PI / res;
    float sectorAngle, stackAngle;
    for(int i = 0; i <= res; ++i){
        stackAngle = PI / 2 - i * stackStep;
        float xy = r * sinf(stackAngle);
        float z = r * cosf(stackAngle);
        for(int j = 0; j <= res; ++j){
            sectorAngle = j * sectorStep;
            float x = xy * sinf(sectorAngle);
            float y = xy * cosf(sectorAngle);
            vertices.push_back(glm::vec3(x,y,z));
        }
    }
    glGenVertexArrays(1, &VAO);
    glGenBuffers(1, &verticesVBO);
    glBindVertexArray(VAO);
    glBindBuffer(GL_ARRAY_BUFFER, verticesVBO);
    glBufferData(GL_ARRAY_BUFFER, vertices.size(), vertices.data(), GL_STATIC_DRAW);
    
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
    glEnableVertexAttribArray(0);
    glBindVertexArray(0);

And here it's how I draw it:

    glm::mat4 projection = glm::perspective(glm::radians(camera.getFOV()), (float) SCR_WIDTH / (float) SCR_HEIGHT, 0.1f, 100.0f);
    glm::mat4 view = camera.getViewMatrix();

    glm::mat4 model = glm::mat4(1.0f);
    shader.use();
    shader.setUniform("projection_view", projection*view);
    shader.setUniform("model", model);
    glBindVertexArray(sphere.VAO);
    glDrawArrays(GL_POINTS, 0, sphere.vertices.size());

I wanted to draw the vertices first and then move to drawing the triangles.

Sorry if this is a stupid question.

\$\endgroup\$
1

2 Answers 2

0
\$\begingroup\$

This line says your stackAngle is measured from 0 at z = +r to PI at z = -r:

float z = r * cosf(stackAngle);

But this line says your stackAngle goes from PI/2 (where z is 0) to -PI/2 (where z is 0 again):

stackAngle = PI / 2 - i * stackStep;

In between, stackAngle will pass over over 0 (where z = +r), but it will never visit +-PI (where z = -r).

So you're doubling over the top hemisphere and missing the bottom entirely.

It looks like you want:

// stackAngle is "radians south of the north pole,"
// running from 0 to PI. Keep xy = sin, z = cos.
stackAngle = i * stackStep;
float xy = r * sinf(stackAngle);
float z = r * cosf(stackAngle);

or:

// stackAngle is "radians north of the equator,"
// running from PI/2 to -PI/2. Swap sin & cos between xy & z.
stackAngle = PI / 2 - i * stackStep;
float xy = r * cosf(stackAngle);
float z = r * sinf(stackAngle);
\$\endgroup\$
2
  • \$\begingroup\$ Oh! Thank you, the explanation was very clear! Unfortunately this is what I have now, which is even weirder. I guess it could be because of my view matrix? imgur.com/a/8vvJVW6 \$\endgroup\$
    – Syrinxos
    Feb 23, 2021 at 13:22
  • \$\begingroup\$ To check for that, try setting your res quite low and print out the points you get. Then you can verify whether they're covering the correct positions (and the rendering must be the problem) or if the numbers you're outputting are wrong (and the rendering is faithfully showing what you gave it) \$\endgroup\$
    – DMGregory
    Feb 23, 2021 at 13:25
0
\$\begingroup\$

To sum it up: the formula I was using was wrong, as @DMGregory suggested.

But I was also passing vertices.size() as the dimension of the vertices vector, while the correct line would have been:

glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(glm::vec3), vertices.data(), GL_STATIC_DRAW);
\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .