在使用纹理的时候,有时候会出现超过纹理边界的问题,GL_TEXTURE_WRAP系列参数用来设置当这些超出边界时应该怎样处理。下面结合代码和代码产生的结果进行说明每个参数的作用。代码基于红宝书——《opengl编程指南》7th上的代码,自己再稍微改改,用来产生各种效果。
- #include "stdafx.h"
- #include <GL/glew.h>
- #include <GL/glut.h>
- #define checkImageWidth 64
- #define checkImageHeight 64
- static GLubyte checkImage[checkImageHeight][checkImageWidth][4];
- static GLuint texName;
- //产生纹理的函数
- 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);
- glGenTextures(1,&texName);
- glBindTexture(GL_TEXTURE_2D,texName);
- // glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP); //GL_CLAMP GL_CLAMP_TO_BORDER
- // glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP); //GL_REPEAT GL_CLAMP_TO_EDGE
- glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
- glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
- float color[4] = { 1.0f, 0.0f, 0.0f, 1.0f };
- glTexParameterfv( GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, color);
- 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_RGBA,checkImageWidth,checkImageHeight,
- 0,GL_RGBA,GL_UNSIGNED_BYTE,checkImage);
- }
- 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_REPLACE);
- glBindTexture(GL_TEXTURE_2D,texName);
- glBegin( GL_QUADS );
- glTexCoord2f( 0.0, 0.0);
- glVertex2f( -1.0, -1.0);
- glTexCoord2f( 0.0, 1.8 );
- glVertex2f( -1.0, 1.0 );
- glTexCoord2f( 1.8, 1.8 );
- glVertex2f( 1.0, 1.0 );
- glTexCoord2f( 1.8, 0.0 );
- glVertex2f ( 1.0, -1.0 );
- glEnd( );
- glFlush();
- }
- int main(int argc, char* argv[])
- {
- glutInit(&argc, argv);
- glutInitDisplayMode( GLUT_SINGLE|GLUT_RGBA);
- glutInitWindowSize(512, 512);
- glutInitWindowPosition(0, 0);
- glutCreateWindow("棋盘纹理");
- glutDisplayFunc(display);
- glutIdleFunc(display);
- init();
- glutMainLoop();
- return 0;
- }
1. 首先是GL_REPEAT,这个比较简单,就是重复边界的纹理。产生的效果如下:
2. GL_CLAMP采用这种模式是,opengl就在一个2X2的加权纹理单元数组中使用取自边框的纹理单元。这时候的边框如果没有设置的话,应该就是原纹理的边界的像素值。
3. GL_CLAMP_TO_EDGE,在这种模式下,边框始终被忽略。位于纹理边缘或者靠近纹理边缘的纹理单元将用于纹理计算,但不使用纹理边框上的纹理单元。在实验中,不管有没有设置边框,都与与上面的GL_CLAMP结果相同。在下面的参考文献中给了一个解释:因为很多硬件并不支持边界处理,所以实现GL_CLAMP_TP_EDGE和GL_CLAMP的效果好象是一样的。
4. GL_CLAMP_TO_BORDER如果纹理坐标位于范围[0,1]之外,那么只用边框纹理单元(如果没有边框,则使用常量边框颜色,我想常量边框颜色就是黑色)用于纹理。在靠近纹理坐标边缘的地方,无论是边框还是纹理内部都可能根据一个2X2的数组进行采样。
5. 在GL_CLAMP_TO_BORDER的基础上使用上面的代码设置GL_TEXTURE_BORDER_COLOR(设置边框颜色为红色),可以得到下面的结果:
转载自:http://blog.csdn.net/mutex86/article/details/9023863