我刚开始使用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();
}
任何帮助都会非常感激。
答案 0 :(得分:2)
一些注意事项:在固定功能pipleine中,必须在将视图转换(=相机)应用于模型视图矩阵后设置灯光位置。实际上,init()中的整个代码实际上属于display函数。
glClearDepth应该设置为1,除非你知道,你正在做什么(清晰的深度在NDC空间中工作,作为一个OpenGL初学者,这对于一个起点来说是“太高级”了。只需将它设置为1并且开心。
map()函数毫无意义。纹理初始化一次,然后仅在渲染纹理几何体之前进行绑定。
最后但并非最不重要的是,glutSolidSphere不会生成正确的纹理坐标。但是你需要给出OpenGL纹理坐标。我的建议:沟槽glutSolidSphere并自己做几何。像这样:https://stackoverflow.com/a/5989676/524368