0

I am modifying the excellent code provided in this answer Creating a 3D sphere in Opengl using Visual C++ to suit my needs, which is to draw it using GL_TRIANGLES and face culling like this:

GLCALL(glEnable(GL_CULL_FACE));
GLCALL(glCullFace(GL_BACK));
GLCALL(glFrontFace(GL_CCW));

I've managed to make the indices work for triangles, but I cant bloody figure out how to eliminate the cull face problem; as it is, it culls the wrong face using the indice setup I got below:

bool CreateSphereData(const float radius, const uint32_t rings, const uint32_t sectors, std::vector<float>& vertexData, std::vector<float>& normalData, std::vector<float>& texcoordData, std::vector<uint32_t>& indiceData)
{
    if (radius <= 0 || rings <= 0 || sectors <= 0)
        return false;

    const float R = 1.0f / (float)(rings - 1);
    const float S = 1.0f / (float)(sectors - 1);
    const float pi = boost::math::constants::pi<float>();
    const float pi_2 = pi / 2;

    vertexData.resize(rings * sectors * 3);
    normalData.resize(rings * sectors * 3);
    texcoordData.resize(rings * sectors * 2);
    auto v = vertexData.begin();
    auto n = normalData.begin();
    auto t = texcoordData.begin();
    for (uint32_t r = 0; r < rings; r++)
    {
        for (uint32_t s = 0; s < sectors; s++)
        {
            const float y = sin(-pi_2 + pi * r * R);
            const float x = cos(2 * pi * s * S) * sin(pi * r * R);
            const float z = sin(2 * pi * s * S) * sin(pi * r * R);

            *t++ = s*S;
            *t++ = r*R;

            *v++ = x * radius;
            *v++ = y * radius;
            *v++ = z * radius;

            *n++ = x;
            *n++ = y;
            *n++ = z;
        }
    }

    indiceData.resize(rings * sectors * 6);
    auto i = indiceData.begin();
    for (uint32_t r = 0; r < rings; r++)
    {
        for (uint32_t s = 0; s < sectors; s++)
        {
            *i++ = (r + 1) * sectors + s;
            *i++ = r * sectors + s;
            *i++ = r * sectors + (s + 1);

            *i++ = (r + 1) * sectors + (s + 1);
            *i++ = (r + 1) * sectors + s;
            *i++ = r * sectors + (s + 1);
        }
    }

    return true;
}

I am sure it is simple but I can't get it right. Any pointers?

EDIT/ANSWER:

Simply the following indices draws it correctly with setup mentioned above:

    indiceData.resize(rings * sectors * 6);
    auto i = indiceData.begin();
    for (uint32_t r = 0; r < rings-1; r++)
    {
        for (uint32_t s = 0; s < sectors-1; s++)
        {
            *i++ = r * sectors + (s + 1);
            *i++ = r * sectors + s;
            *i++ = (r + 1) * sectors + s;

            *i++ = r * sectors + (s + 1);
            *i++ = (r + 1) * sectors + s;
            *i++ = (r + 1) * sectors + (s + 1);
        }
    }
Community
  • 1
  • 1
KaiserJohaan
  • 9,028
  • 20
  • 112
  • 199
  • You forgot to tell us what the "face culling problem" is. All I can see is your last two loops have incorrect bounds, if you compare against the original code. – DanielKO Dec 02 '13 at 23:21
  • The front of the sphere is culled rather than the back - why does it have incorrect bounds? – KaiserJohaan Dec 03 '13 at 07:36
  • The original code iterates up to `r < rings-1`, same for `s < sectors-1`. Also you are generate indices in a completely different way. Why did you expect your code to work in the first place? – DanielKO Dec 03 '13 at 08:09

0 Answers0