#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向重复,如下图所示