#include <Windows.h> #include <gl/GLU.h> #include <gl/glaux.h> #include <GL/glut.h> #include <stdio.h> static GLuint texName; AUX_RGBImageRec * CreateTextureFromBmp() { FILE *File=NULL; const char *Filename= "hehua.bmp"; File=fopen(Filename,"r"); if (!File) return 0; fclose(File); return auxDIBImageLoad(Filename); } void init(void) { glClearColor (0.0, 0.0, 0.0, 0.0); glShadeModel(GL_FLAT); glEnable(GL_DEPTH_TEST); AUX_RGBImageRec * imageRec = CreateTextureFromBmp(); if (!imageRec) exit(EXIT_FAILURE); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); glGenTextures(1, &texName); glBindTexture(GL_TEXTURE_2D, texName); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); 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_RGB, imageRec->sizeX, imageRec->sizeX, 0, GL_RGB, GL_UNSIGNED_BYTE, imageRec->data); } void display(void) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glEnable(GL_TEXTURE_2D); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL); glBindTexture(GL_TEXTURE_2D, texName); glBegin(GL_QUADS); glTexCoord2f(0.0, 0.0); glVertex3f(-2.0, -1.0, 0.0); glTexCoord2f(0.0, 1.0); glVertex3f(-2.0, 1.0, 0.0); glTexCoord2f(1.0, 1.0); glVertex3f(0.0, 1.0, 0.0); glTexCoord2f(1.0, 0.0); glVertex3f(0.0, -1.0, 0.0); glTexCoord2f(0.0, 0.0); glVertex3f(1.0, -1.0, 0.0); glTexCoord2f(0.0, 1.0); glVertex3f(1.0, 1.0, 0.0); glTexCoord2f(1.0, 1.0); glVertex3f(2.41421, 1.0, -1.41421); glTexCoord2f(1.0, 0.0); glVertex3f(2.41421, -1.0, -1.41421); glEnd(); glFlush(); glDisable(GL_TEXTURE_2D); } void reshape(int w, int h) { glViewport(0, 0, (GLsizei) w, (GLsizei) h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(60.0, (GLfloat) w/(GLfloat) h, 1.0, 30.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glTranslatef(0.0, 0.0, -3.6); } int main(int argc, char** argv) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH); glutInitWindowSize(250, 250); glutInitWindowPosition(100, 100); glutCreateWindow(argv[0]); init(); glutDisplayFunc(display); glutReshapeFunc(reshape); glutMainLoop(); return 0; }
程序截图
将GL_NEAREST改成GL_LINEAR,效图如下图。左边为NEARST,右边为LINEAR。
可见使用后者,图片锯齿能少很多。
函数解释
void glTexImage2D( GLenum target, GLint level, GLint internalFormat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid * data);参数data
此函数从data加载纹理数据,生成一个纹理。最近一次绑定的纹理ID指向了这个纹理。在此例中即是纹理ID texName指向由glTexImage2D生成的纹理。OpenGL是一个状态机,学习OpenGL时要时刻记着这一点。data的来源可以是内存中的一个数组,也可以是一幅位图的像素部分。如果使用的是位图,来填充data,那么可能会浪费一些空间。因为位图可以大幅压缩。所以可以internalFormat来指定压缩纹理。
参数level
提供纹理图像的数量,在使用多重细节时,使用此值。不使用多重细节时,值为0。
internalFormat 指定纹理的颜色格式。GL_RGBA 颜色格式为(红,绿,蓝,透明度),GL_RGB 颜色格式为(红,绿,蓝)。也可以使用压缩纹理。GL_COMPRESSED_*枚举值。具体参数含义可参看如下链接
参数含义
参数表示纹理图像的宽度和高度。参数表示边框的宽度,它只能是0或者是1.width和height的值都必须是2^m+2b,其中m是非负的整数。height可以使用不同的m值。b是border值。纹理图像的最大值取决于OpenGl实现,但它至少是64x64如果有边框至少是66x66。另外,OpenGL2.0取消了纹理图像必须是2的整数次方的限制。
format指定了像素格式。可使用的值有GL_COLOR_INDEX, GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA, GL_RGB, GL_BGR, GL_RGBA等。
它与internalFormat的区别.internalFormat 可以指定R、G、B各元素的大小。如R可以是3,4,58,...Bit。
type
指定像素的数据类型。可以是GL_FLOAT,GL_UNSIGNED_BYTE等。对于位图来说,一定是GL_UNSIGNED_BYTE.
data
指定图像所在内存的指针。
GL_TEXTURE_WRAP_S GL_TEXTURE_WRAP_T其中S、T是纹理空间内的两个参数坐标。如下图所示
GL_REPEAT含义:当纹理空间与贴图所用的空间不一致时,重复纹理。glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);即在s向重复,如下图所示