Texturing a sphere in OpenGL with glTexGen

I want to get the texture of the ground on the sphere. My sphere is an isosphere built with many triangles (100+) and it was difficult for me to enter UV coordinates for the whole sphere. I tried using glTexGen and the effects are pretty close, but I got the texture repeated 8 times (see image). I can't find a way to get it to just wrap the whole object once. Here is my code where the sphere and textures are created.

    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

+3


source to share


1 answer


You need to define how your texture should map to your triangles. It depends on the texture you are using. There are many ways to map the surface of a sphere to a texture (since none of the mappings are special). It looks like you have a cylindrical projection texture. Therefore, we will emit cylindrical UV coordinates.

I tried to give you the code here, but it assumed that

  • Your mesh is a unit sphere (i.e. centered at 0 and has a radius of 1)
  • pnts.coords

    - array of floats
  • You want to use the second coordinate ( coord[1]

    ) as "up" (or height

    in cylindrical display)

Your code will look something like this. I have defined a new function for emitting cylindrical UV rays, so you can place this wherever you want.



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

      

Note on projections

The reason it confuses the creation of UV coordinates for the entire sphere is because there is no "correct" way to do it. Mathematically speaking, there is no such thing as a perfect two-dimensional map of a sphere; that's why we have so many different types of projections . When you have a 2D image that is a texture for a spherical object, you need to know what type of projection the image was built for so that you can correct the correct UV coordinates for that texture.

+1


source







All Articles