简体   繁体   中英

Texture coordinates for rendering a 3d sphere

I am drawing a 3d sphere using GL_QUAD_STRIP primitive and it works except I don't know how to set up the texture coordinates.

I have a certain number of division that divide my sphere into equal number of latitudes and longitudes. Hence, the sphere's vertices are approximated using the divisions as follows

   float x, y, z, dTheta=180/divisions, dLon=360/divisions, degToRad=3.14/180 ;

    for(float lat =0 ; lat <=180 ; lat+=dTheta)
    {
        glBegin( GL_QUAD_STRIP ) ;
        for(float lon = 0 ; lon <=360; lon+=dLon)
        {  

            x = r*cosf(lat * degToRad) * sinf(lon * degToRad) ;
            y = r*sinf(lat * degToRad) * sinf(lon * degToRad) ;
            z = r*cosf(lon * degToRad) ;

            glNormal3f( x, y, z) ;
            glVertex3f( x, y, z ) ;

            x = r*cosf((lat + dTheta) * degToRad) * sinf(lon * degToRad) ;
            y = r*sinf((lat + dTheta) * degToRad) * sinf(lon * degToRad) ;
            z = r*cosf( lon * degToRad ) ;

            glNormal3f( x, y, z ) ;
            glVertex3f( x, y, z ) ;
        }
        glEnd() ;

    }

如果使用标准失真的球体纹理(如普通的地球贴图),则应使用纹理坐标(例如:lat / 180,lon / 360),即范围为[0..1]的归一化值。

Add new variables :

float texX = 0.0;
float texy = 0.0;
float dTex = 1/ divisions;

then add then to the loop : float x, y, z, dTheta=180/divisions, dLon=360/divisions, degToRad=3.14/180 ;

for(float lat =0 ; lat <=180 ; lat+=dTheta, texX += dTex)
{
    texY = 0.0;
    glBegin( GL_QUAD_STRIP ) ;
    for(float lon = 0 ; lon <=360; lon+=dLon, texY += dTex )
    {  

        x = r*cosf(lat * degToRad) * sinf(lon * degToRad) ;
        y = r*sinf(lat * degToRad) * sinf(lon * degToRad) ;
        z = r*cosf(lon * degToRad) ;

        glNormal3f( x, y, z) ;
        glTexCoord2f( texX, texY );
        glVertex3f( x, y, z ) ;
    }
    glEnd() ;

}

Okay the problem was that I was only drawing 2 vertices and GL_QUAD_STRIP requires 4. The following code now has both vertices set up properly and texture working

   double x, y, z, dTheta=180/divisions, dLon=360/divisions, degToRad=3.141592665885/180 ;

    for(double lat =0; lat <=180; lat+=dTheta)
    {

        glBegin( GL_QUAD_STRIP ) ;
        for(double lon =0 ; lon <=360 ; lon+=dLon)
        {  


            //Vertex 1
            x = r*cos(lon * degToRad) * sin(lat * degToRad) ;
            y = r*sin(lon * degToRad) * sin(lat * degToRad) ;
            z = r*cos(lat * degToRad) ;
            glNormal3d( x, y, z) ;
            glTexCoord2d(lon/360-0.25, lat/180);
            glVertex3d( x, y, z ) ;


            //Vetex 2
            x = r*cos(lon * degToRad) * sin( (lat + dTheta)* degToRad) ;
            y = r*sin(lon * degToRad) * sin((lat + dTheta) * degToRad) ;
            z = r*cos( (lat + dTheta) * degToRad ) ;
            glNormal3d( x, y, z ) ;
            glTexCoord2d(lon/360-0.25, (lat + dTheta-1)/(180)); 
            glVertex3d( x, y, z ) ;


            //Vertex 3
            x = r*cos((lon + dLon) * degToRad) * sin((lat) * degToRad) ;
            y = r*sin((lon + dLon) * degToRad) * sin((lat) * degToRad) ;
            z = r*cos((lat) * degToRad ) ;
            glNormal3d( x, y, z ) ;
           glTexCoord2d((lon + dLon)/(360)-0.25 ,(lat)/180);
             glVertex3d( x, y, z ) ;


            //Vertex 4
            x = r*cos((lon + dLon) * degToRad) * sin((lat + dTheta)* degToRad) ;
            y = r*sin((lon + dLon)* degToRad) * sin((lat + dTheta)* degToRad) ;
            z = r*cos((lat + dTheta)* degToRad ) ;
            glNormal3d( x, y, z ) ;
            glTexCoord2d((lon + dLon)/360-0.25, (lat + dTheta)/(180));
             glVertex3d( x, y, z ) ;


        }
        glEnd() ;

    }

Hope people who get stuck may find this useful.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM