使用glTexGen在OpenGL中纹理球体

时间:2017-05-28 20:37:04

标签: c opengl mapping texturing

我想在球体上获得地球纹理。我的球体是一个由许多三角形(100+)构成的icosphere,我发现设置整个球体的UV坐标会让人感到困惑。我尝试使用glTexGen,效果非常接近但我的纹理重复了8次(见图)。我找不到一种方法让它只包裹整个对象一次。这是我的代码,其中创建了球体和纹理。

    glEnable(GL_TEXTURE_2D);
glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
glBegin(GL_TRIANGLES);

for (int i = 0; i < new_sphere->NumOfTrians; i++)
{
    Triangle *draw_Trian = new_sphere->Trians+i;
    glVertex3f(draw_Trian->pnts[0].coords[0], draw_Trian->pnts[0].coords[1], draw_Trian->pnts[0].coords[2]);
    glVertex3f(draw_Trian->pnts[1].coords[0], draw_Trian->pnts[1].coords[1], draw_Trian->pnts[1].coords[2]);
    glVertex3f(draw_Trian->pnts[2].coords[0], draw_Trian->pnts[2].coords[1], draw_Trian->pnts[2].coords[2]);

}
glDisable(GL_TEXTURE_2D);
free(new_sphere->Trians);
free(new_sphere);

glEnd();

enter image description here

1 个答案:

答案 0 :(得分:1)

您需要定义纹理应如何映射到三角形。这取决于您使用的纹理。有多种方法可以用纹理映射球体表面(因为没有一个映射没有奇点)。看起来你有一个圆柱投影纹理。所以我们将发射圆柱形UV坐标。

我试图在这里给你一些代码,但它假设

  • 您的网格是一个单位球体(即以0为中心,半径为1)
  • pnts.coords是一个浮点数组
  • 您希望将第二个坐标(coord[1])用作“向上”方向(或圆柱映射中的height

您的代码看起来像这样。我已经定义了一个用于发射圆柱形UV的新功能,因此您可以将它放在任何您喜欢的地方。

/* Map [(-1, -1, -1), (1, 1, 1)] into [(0, 0), (1, 1)] cylindrically */
inline void uvCylinder(float* coord) {
  float angle = 0.5f * atan2(coord[2], coord[0]) / 3.14159f + 0.5f;
  float height = 0.5f * coord[1] + 0.5f;
  glTexCoord2f(angle, height);
}

glEnable(GL_TEXTURE_2D);
glBegin(GL_TRIANGLES);

for (int i = 0; i < new_sphere->NumOfTrians; i++) {
  Triangle *t = new_sphere->Trians+i;

  uvCylinder(t->pnts[0].coords);
  glVertex3f(t->pnts[0].coords[0], t->pnts[0].coords[1], t->pnts[0].coords[2]);
  uvCylinder(t->pnts[1].coords);
  glVertex3f(t->pnts[1].coords[0], t->pnts[1].coords[1], t->pnts[1].coords[2]);
  uvCylinder(t->pnts[2].coords);
  glVertex3f(t->pnts[2].coords[0], t->pnts[2].coords[1], t->pnts[2].coords[2]);

}

glEnd();
glDisable(GL_TEXTURE_2D);

free(new_sphere->Trians);
free(new_sphere);

关于预测的说明

为整个球体构建UV坐标令人困惑的原因是没有一种“正确”的方法可以做到这一点。从数学的角度来说,没有一个完美的球体2D映射;因此,为什么我们有这么多不同类型的projections。如果您的2D图像是球形对象的纹理,则需要知道为其构建图像的投影类型,以便您可以为该纹理发出正确的UV坐标。