纹理随gluSphere和glutPostRedisplay消失

时间:2011-12-04 12:25:47

标签: c++ opengl

我刚开始使用opengl。事实上,这是我的第一个项目。 我想将一些纹理映射到背景中的四边形,并希望在前面使用gluSphere绘制一个球体,我想要为此设置动画。所以,我首先映射纹理,然后在显示函数中绘制球体,然后调用glutPostRedisplay。首次调用显示时,它会正确显示纹理和球体。但是,一旦调用了glutPostRedisplay,纹理就会消失,只会绘制球体。我在下面给出了我的代码。我为使用任何糟糕的opengl做法道歉。

void display() {
    glClear(GL_COLOR_BUFFER_BIT);
    drawTex();
    glPushMatrix();
    glTranslatef(SIZE/2, SIZE/2, 0);
    glutSolidSphere(15.0, 20, 20);
    glPopMatrix();
    glutSwapBuffers();
    glutPostRedisplay();    
}

void LoadTextureRAW( const char * filename, int wrap ) {
    GLuint texture;
    int width, height;
    unsigned char * data;

    FILE * file;
    // open texture data
    file = fopen( filename, "rb" );
    if ( file == NULL ) {
        return;    
    }

    // allocate buffer
    width = 1073;
    height = 918;    
    data = (unsigned char *)malloc( width * height * 3 );

    // read texture data
    fclose( file );

    // select our current texture
    glBindTexture( GL_TEXTURE_2D, 1 );

    // select modulate to mix texture with color for shading
    glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );

    // when texture area is small, bilinear filter the closest mipmap
    glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST );

    // when texture area is large, bilinear filter the first mipmap
    glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );

    // if wrap is true, the texture wraps over at the edges (repeat)
    // ... false, the texture ends at the edges (clamp)
    glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrap ? GL_REPEAT : GL_CLAMP );
    glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrap ? GL_REPEAT : GL_CLAMP );

    // build our texture mipmaps
    gluBuild2DMipmaps( GL_TEXTURE_2D, 3, width, height,
    GL_RGB, GL_UNSIGNED_BYTE, data );

    // free buffer
    free( data );    
}

void drawTex() {
    glBegin(GL_QUADS);
    glTexCoord2d(0.0,0.0);
    glVertex3d(0.0,SIZE/2, -SIZE);
    glTexCoord2d(1.0,0.0);
    glVertex3d(SIZE, SIZE/2, -SIZE);
    glTexCoord2d(1.0,1.0);
    glVertex3d(SIZE, SIZE/2, SIZE);
    glTexCoord2d(0.0,1.0);
    glVertex3d(0.0, SIZE/2, SIZE);
    glEnd();    
    glFlush();    
}

void map() {
    glClearColor(1.0, 1.0, 1.0, 1.0);
    glClear(GL_COLOR_BUFFER_BIT);
    glEnable( GL_TEXTURE_2D );
    LoadTextureRAW("background.bmp", true);    
    glBindTexture( GL_TEXTURE_2D, 1 );    
    drawTex();
}

void init() {
    glClearColor(1, 1, 1, 1);
    glClearDepth( SIZE );
    glOrtho(0, SIZE, 0, SIZE, -SIZE, SIZE);
    GLfloat mat_ambient[] = { 1.0, 1.0, 1.0, 1.0 };
    GLfloat mat_specular[] = { 1.0, 1.0, 1.0, 1.0 };
    GLfloat mat_shininess[] = { 50.0 };
    GLfloat light_position[] = { SIZE/2, 0, 1.0, 0.0 };
    GLfloat model_ambient[] = { 0.5, 0.5, 0.5, 1.0 };    
    glClearColor(1.0, 1.0, 1.0, 1.0);    

    glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient);    
    glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);    
    glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);    
    glLightfv(GL_LIGHT0, GL_POSITION, light_position);    
    glLightModelfv(GL_LIGHT_MODEL_AMBIENT, model_ambient);    
    //glColor3f(0,0,0);    
    glEnable(GL_LIGHTING);    
    glEnable(GL_LIGHT0);    
    glRotatef(-40, 1, 0, 0);    
    glRotatef(-40, 0, 1, 0);    
    map();
}

任何帮助都会非常感激。

1 个答案:

答案 0 :(得分:2)

一些注意事项:在固定功能pipleine中,必须在将视图转换(=相机)应用于模型视图矩阵后设置灯光位置。实际上,init()中的整个代码实际上属于display函数。

glClearDepth应该设置为1,除非你知道,你正在做什么(清晰的深度在NDC空间中工作,作为一个OpenGL初学者,这对于一个起点来说是“太高级”了。只需将它设置为1并且开心。

map()函数毫无意义。纹理初始化一次,然后仅在渲染纹理几何体之前进行绑定。

最后但并非最不重要的是,glutSolidSphere不会生成正确的纹理坐标。但是你需要给出OpenGL纹理坐标。我的建议:沟槽glutSolidSphere并自己做几何。像这样:https://stackoverflow.com/a/5989676/524368