How do I texture a cylinder in OpenGL created with triangle_strip?

后端 未结 2 790
醉话见心
醉话见心 2021-01-20 15:40

Here\'s the cylinder I have created:

void drawCylinder(float r, float g, float b) {
    setMaterialColors(r, g, b);
    glColor4f(r, g, b, 1.0);
    /* top t         


        
2条回答
  •  礼貌的吻别
    2021-01-20 16:14

    For the center: Divide i by 2 * PI to get a number that varies between 0.0 and 1.0 and use that as a texture coordinate:

    for (i = 0; i <= 2 * PI; i += resolution)
    {
        const float tc = ( i / (float)( 2 * PI ) );
        glTexCoord2f( tc, 0.0 );
        glVertex3f(radius * cos(i), 0, radius * sin(i));
        glTexCoord2f( tc, 1.0 );
        glVertex3f(radius * cos(i), height, radius * sin(i));
    }
    
    /* close the loop back to zero degrees */
    glTexCoord2f( 0.0, 0.0 );
    glVertex3f(radius, 0, 0);
    glTexCoord2f( 0.0, 1.0 );
    glVertex3f(radius, height, 0);
    

    For the endcaps: You can use the sin()/cos() output (almost) directly:

    glTexCoord2f( 0.5, 0.5 );
    glVertex3f(0, height, 0);  /* center */
    for (i = 0; i <= 2 * PI; i += resolution)
    {
        // scale sin/cos range (-1 to 1) by 0.5 to get -0.5 to 0.5
        // then shift that range up/right by 0.5 to get 0 to 1:
        glTexCoord2f( 0.5f * cos(i) + 0.5f, 0.5f * sin(i) + 0.5f );
        glVertex3f(radius * cos(i), height, radius * sin(i));
    }
    

    Complete example:

    #include 
    #include 
    #include 
    
    void cylinder()
    {
        const double PI = 3.14159;
    
        /* top triangle */
        double i, resolution  = 0.1;
        double height = 1;
        double radius = 0.5;
    
        glPushMatrix();
        glTranslatef(0, -0.5, 0);
    
        glBegin(GL_TRIANGLE_FAN);
            glTexCoord2f( 0.5, 0.5 );
            glVertex3f(0, height, 0);  /* center */
            for (i = 2 * PI; i >= 0; i -= resolution)
    
            {
                glTexCoord2f( 0.5f * cos(i) + 0.5f, 0.5f * sin(i) + 0.5f );
                glVertex3f(radius * cos(i), height, radius * sin(i));
            }
            /* close the loop back to 0 degrees */
            glTexCoord2f( 0.5, 0.5 );
            glVertex3f(radius, height, 0);
        glEnd();
    
        /* bottom triangle: note: for is in reverse order */
        glBegin(GL_TRIANGLE_FAN);
            glTexCoord2f( 0.5, 0.5 );
            glVertex3f(0, 0, 0);  /* center */
            for (i = 0; i <= 2 * PI; i += resolution)
            {
                glTexCoord2f( 0.5f * cos(i) + 0.5f, 0.5f * sin(i) + 0.5f );
                glVertex3f(radius * cos(i), 0, radius * sin(i));
            }
        glEnd();
    
        /* middle tube */
        glBegin(GL_QUAD_STRIP);
            for (i = 0; i <= 2 * PI; i += resolution)
            {
                const float tc = ( i / (float)( 2 * PI ) );
                glTexCoord2f( tc, 0.0 );
                glVertex3f(radius * cos(i), 0, radius * sin(i));
                glTexCoord2f( tc, 1.0 );
                glVertex3f(radius * cos(i), height, radius * sin(i));
            }
            /* close the loop back to zero degrees */
            glTexCoord2f( 0.0, 0.0 );
            glVertex3f(radius, 0, 0);
            glTexCoord2f( 0.0, 1.0 );
            glVertex3f(radius, height, 0);
        glEnd();
    
        glPopMatrix();
    }
    
    GLuint tex;
    void init()
    {
        unsigned char data[] =
        {
            128, 128, 128, 255,
            255, 0, 0, 255,
            0, 255, 0, 255,
            0, 0, 255, 255,
        };
    
        glGenTextures( 1, &tex );
        glBindTexture( GL_TEXTURE_2D, tex );
        glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
        glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
        glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
        glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
        glTexImage2D( GL_TEXTURE_2D, 0,GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, data );
    }
    
    float angle = 0;
    void timer( int value )
    {
        angle += 6;
        glutPostRedisplay();
        glutTimerFunc( 16, timer, 0 );
    }
    
    void display()
    {
        glClearColor( 0, 0, 0, 1 );
        glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
    
        glMatrixMode( GL_PROJECTION );
        glLoadIdentity();
        gluPerspective( 60, 1.0, 0.1, 100.0 );
    
        glMatrixMode( GL_MODELVIEW );
        glLoadIdentity();
        glTranslatef( 0, 0, -5 );
    
        glEnable( GL_CULL_FACE );
        glEnable( GL_DEPTH_TEST );
    
        glRotatef( angle, 0.2, 0.3, 0.1 );
    
        glEnable( GL_TEXTURE_2D );
        glBindTexture( GL_TEXTURE_2D, tex );
        cylinder();
    
        glutSwapBuffers();
    }
    
    int main(int argc, char **argv)
    {
        glutInit( &argc, argv );
        glutInitDisplayMode( GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE );
        glutInitWindowSize( 600, 600 );
        glutCreateWindow( "GLUT" );
        init();
        glutDisplayFunc( display );
        glutTimerFunc( 0, timer, 0 );
        glutMainLoop();
        return 0;
    }
    

提交回复
热议问题