现在的位置: 首页 > 综合 > 正文

GL_TEXTURE_WRAP系列参数的取值

2013年10月10日 ⁄ 综合 ⁄ 共 2760字 ⁄ 字号 评论关闭

在使用纹理的时候,有时候会出现超过纹理边界的问题,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(设置边框颜色为红色),可以得到下面的结果:

参考文献:

1.http://blog.csdn.net/superkris/article/details/5567593

2.http://blog.163.com/ray_jun/blog/static/167053642201162493648552/

3.《opengl编程指南》第七版9.6.2节——重复和截取纹理

抱歉!评论已关闭.