【问题标题】:Incomplete sphere OpenGL不完整的球体OpenGL
【发布时间】:2014-11-17 12:40:44
【问题描述】:

我想使用 VBO 绘制一个球体作为顶点、颜色和 UV 坐标作为纹理。我的问题是球体没有“封闭”,原点有一个洞。我知道这是因为我的代码取决于每个顶点之间的 (1/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....

这是我的输出:

【问题讨论】:

    标签: c++ opengl geometry draw vbo


    【解决方案1】:

    我不认为这是一个漏洞。您绘制了太多的线段,并导致它在南极绘制额外的三角形,并且纹理环绕:

    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);
    

    【讨论】:

    • 非常感谢!这非常容易理解!现在我看到了。
    猜你喜欢
    • 1970-01-01
    • 2019-05-03
    • 2012-09-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-21
    • 1970-01-01
    相关资源
    最近更新 更多