OpenGL不完整的球体

4
我想使用VBO绘制一个球体,其中包括顶点、颜色和纹理的UV坐标。我的问题是球体不是“封闭”的,原点处有一个孔。我知道这是因为我的代码依赖于每个顶点之间的(1/segments)距离; 我正在使用segments = 40。我知道如果提高该值,则孔将变小,但程序会变慢。我不知道是否有一种方法可以消除孔而不提高变量。
以下是代码:
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....

这是我的输出结果:

在此输入图片描述

1个回答

2

我认为那不是一个洞。您画了一个多余的线段,导致在南极绘制额外的三角形,并且贴图被包裹在上面:

for(int i = 0; i <= segments; i++){
    double lat0 = pi * (-0.5 + (double)(i - 1) / segments);

在第一次循环迭代中,当i = 0时,角度将小于-0.5*pi,导致图片中显示了额外的三角形。
如果您想将纬度范围分为segments段,则只需通过外层循环运行segments次。由上面给出的代码,从0segments,您需要迭代segments + 1次。
最简单的方法是从1开始循环:
for(int i = 1; i <= segments; i++){
    double lat0 = pi * (-0.5 + (double)(i - 1) / segments);

我可能会从0开始循环,并使结束时不包含最后一个元素,同时更改角度计算。但这实际上是等效的:

for(int i = 0; i < segments; i++){
    double lat0 = pi * (-0.5 + (double) / segments);
    ...
    double lat1 = pi * (-0.5 + (double)(i + 1) / segments);

非常感谢!这非常容易理解!现在我明白了。 - MikeFadeCrew

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接