OPENGL学习笔记整理(二):纹理知多少?

OPENGL玩了这么久,有几个地方一直比较犯晕,纹理就是其中之一。这些年,由于着色语言啊,CUDA的出现,个人感觉复杂的纹理设置可以淘汰了,至少已经处于比较边缘的地方了。

还是先从最简单最基本的纹理说起吧。

先把红宝书上的 ckecker.c 抄下来。

复制代码
#include < GL / glut.h >
#include
< stdlib.h >
#include
< stdio.h >

/* Create checkerboard texture */
#define checkImageWidth 64
#define checkImageHeight 64
static GLubyte checkImage[checkImageHeight][checkImageWidth][ 4 ];

#ifdef GL_VERSION_1_1
static GLuint texName;
#endif

void makeCheckImage( void )
{
int i, j, c;

for (i = 0 ; i < checkImageHeight; i ++ ) {
for (j = 0 ; j < checkImageWidth; j ++ ) {
c
= ((((i & 0x8 ) == 0 ) ^ ((j & 0x8 )) == 0 )) * 255 ;
checkImage[i][j][
0 ] = (GLubyte) c;
checkImage[i][j][
1 ] = (GLubyte) c;
checkImage[i][j][
2 ] = (GLubyte) c;
checkImage[i][j][
3 ] = (GLubyte) 255 ;
}
}
}

void init( void )
{
glClearColor (
0.0 , 0.0 , 0.0 , 0.0 );
glShadeModel(GL_FLAT);
glEnable(GL_DEPTH_TEST);

makeCheckImage();
glPixelStorei(GL_UNPACK_ALIGNMENT,
1 );

#ifdef GL_VERSION_1_1
glGenTextures(
1 , & texName);
glBindTexture(GL_TEXTURE_2D, texName);
#endif

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);
#ifdef GL_VERSION_1_1
glTexImage2D(GL_TEXTURE_2D,
0 , GL_RGBA, checkImageWidth, checkImageHeight,
0 , GL_RGBA, GL_UNSIGNED_BYTE, checkImage);
#else
glTexImage2D(GL_TEXTURE_2D,
0 , 4 , checkImageWidth, checkImageHeight,
0 , GL_RGBA, GL_UNSIGNED_BYTE, checkImage);
#endif
}

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);
#ifdef GL_VERSION_1_1
glBindTexture(GL_TEXTURE_2D, texName);
#endif

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 );
}

void keyboard (unsigned char key, int x, int y)
{
switch (key) {
case 27 :
exit(
0 );
break ;
default :
break ;
}
}

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);
glutKeyboardFunc(keyboard);
glutMainLoop();
return 0 ;
}
复制代码

自然,我们着重要说的是设定纹理的过程,即 void init(void) 函数的内容。

这个函数中调用的OPENGL的各个函数具体什么意思,都可以查到。个人觉得有些不用非要去查个水落石出,知道它必须放在这里就好了。glPixelStorei这个函数,以前没调用纹理的时候没有出现过,看来是必备的了。顾名思义就是像素存储格式啊。OK,剩下的这几个就是初始设置纹理了。先要取个名字,这个就让系统来吧。glGenTextures, void glGenTextures(GLsizei n, GLuint *textureNames),看名字就知道怎么用了。有了名字,当然要绑定一下,名字当然要关联到具体的“人”啦,glBindTexture。然后,这个“人”,我们要具体描述一下,最简单的描述法,各个方向的环绕模式以及放大和缩小了的时候的过滤模式,这些都是用同一个函数来设定的glTexParameteri,第一个参数是现在用的是几维纹理,第二个是具体要设定的内容,环绕模式啊还是其他什么的,第三个就是设定成什么样子。这些都做完了之后,就可以把纹理真正地用上去了。这里是glTexImage2D,其实,根据纹理的维数不同,函数也是稍微有点差异的。这个例子里面的坐标是手动设定的,glTexCoord2f,这个也是纹理维数不同,设定坐标的函数有些许差异。还有一个函数在display中,glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_REPLACE)记住这个一般就OK了,GL_REPLACE倒不是很常用的设置,改成GL_MODULATE什么的,各个参数具体意思,有兴趣可以查查,参数种类比较丰富。不过现在,一般用不到那些太复杂东西了,当然,你要搞多重纹理什么的,还是要弄清楚。但是,复杂的纹理,更好用的还是用着色语言写点东西比较好。

有的时候,我们需要替换纹理的一部分纹理或者取去纹理中的一部分内容,这些都有可以查到的简单函数。而且我平时极少用到,这里也就忽略了。

但是,自动生成纹理坐标还是要说一下的。void glTexGen{ifd}(GLenum coord, GLenum pname, TYPE param); void glTexGen{ifd}v(GLenum coord, GLenum pname, const TYPE *param)。以前曾经搞这个累的半死,后来终于弄懂了,貌似以前在博客里写过了,这里就不再重复了。也可以去参考下MSDN,http://msdn.microsoft.com/zh-cn/library/ms537230(v=VS.85).aspx

至于球纹理和立方体纹理,看是看过了,但在实际操作中还真没用到过。这里也不说了,还是和着色语言一起说好了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值