テクスチャ・パラメタ


テクスチャの処理方法を設定する

テクスチャを描画する方形のテクスチャ座標が
テクスチャ画像の大きさよりも小さい場合、テクスチャはどのように描画されるのでしょうか
このような場合、拡大されるか繰り返されるか、何も描画されないかが考えられます
OpenGL の答えは、繰り返して描画するというものです

例えば、次のプログラムを実行するとテクスチャが繰り返されるのを確認できます
#include <windows.h>
#include <GL/gl.h>
#include <GL/glut.h>

#define TEXSIZE 64

GLubyte pixels[TEXSIZE][TEXSIZE][3];
GLuint texName;

void disp( void ) {
	glClear(GL_COLOR_BUFFER_BIT);
	glBindTexture(GL_TEXTURE_2D , texName);

	glBegin(GL_POLYGON);
		glTexCoord2f(0 , 0); glVertex2f(-0.9 , -0.9);
		glTexCoord2f(0 , 2); glVertex2f(-0.9 , 0.9);
		glTexCoord2f(2 , 2); glVertex2f(0.9 , 0.9);
		glTexCoord2f(2 , 0); glVertex2f(0.9 , -0.9);
	glEnd();
	glFlush();
}

int main(int argc , char ** argv) {
	unsigned int i , j;

	for (i = 0 ; i < TEXSIZE ; i++) {
		int r = (i * 0xFF) / TEXSIZE;
		for (j = 0 ; j < TEXSIZE ; j++) {
			pixels[i][j][0] = (GLubyte)r;
			pixels[i][j][1] = (GLubyte)(( j * 0xFF ) / TEXSIZE);
			pixels[i][j][2] = (GLubyte)~r;
		}
	}

	glutInit(&argc , argv);
	glutInitWindowSize(400 , 300);
	glutInitDisplayMode(GLUT_SINGLE | GLUT_RGBA | GLUT_DEPTH);
	
	glutCreateWindow("Kitty on your lap");
	glutDisplayFunc(disp);

	glEnable(GL_TEXTURE_2D);
	glGenTextures(1 , &texName);
	glBindTexture(GL_TEXTURE_2D , texName);

	glTexImage2D(
		GL_TEXTURE_2D , 0 , 3 , TEXSIZE , TEXSIZE ,
		0 , GL_RGB , GL_UNSIGNED_BYTE , pixels
	);

	glutMainLoop();

	glDeleteTextures(1 , &texName);
	return 0;
}


glTexCoord2f() 関数で指定している座標は、右上の頂点がテクスチャの2倍の位置を指しています
この座標では、テクスチャ画像からはみ出るため、画像が繰り返しています

テクスチャの用途の大半は、壁や衣装の模様などだと思われるので
この仕様は、多くのテクスチャでは歓迎されるものでしょう

繰り返すことが好ましくない場合、画像を引き伸ばすことも可能です
この場合は、最終的にテクスチャ画像サイズに合わせてテクスチャが描画されます
この設定をするには glTexParameter() 関数を使います
void glTexParameterf(
  GLenum target, 
  GLenum pname,  
  GLfloat param  
);
 
void glTexParameteri(
  GLenum target, 
  GLenum pname,  
  GLint param    
);
void glTexParameterfv(
  GLenum target,         
  GLenum pname,          
  const GLfloat *params  
);
 
void glTexParameteriv(
  GLenum target,       
  GLenum pname,        
  const GLint *params  
);
target には GL_TEXTURE_1D または GL_TEXTURE_2D を指定します
pname には設定を変更するテクスチャ・パラメタを定数で指定します
ここには、次のいずれかの定数を指定します

定数解説
GL_TEXTURE_MIN_FILTERテクスチャ縮小関数を設定します
GL_TEXTURE_MAG_FILTERテクスチャ拡張関数を設定します
GL_TEXTURE_WRAP_Sテクスチャ座標 s のラップ・パラメタを設定します
GL_CLAMP または GL_REPEAT を設定することができます
GL_TEXTURE_WRAP_Tテクスチャ座標 t のラップ・パラメタを設定します
GL_CLAMP または GL_REPEAT を設定することができます
GL_TEXTURE_BORDER_COLORRGBA 形式で境界の色を設定します
カラー要素は 1 が最も高く、-1 が最も低いことを表します
GL_TEXTURE_PRIORITY0 〜 1 の範囲でテクスチャの優先度を設定します

param 及び params には、pname で設定したパラメタにしたがって
新しいテクスチャ・パラメタの値を指定します
この場では、GL_TEXTURE_WRAP_S と GL_TEXTURE_WRAP_T を使います
そのため、param には GL_CLAMP か GL_REPEAT のいずれかを設定しましょう

GL_TEXTURE_WRAP_S は s 座標、GL_TEXTURE_WRAP_T は t 座標を表します
テクスチャの座標は (0 , 0) を原点とした (s , t) という座標を持っています
s 座標や t 座標を固定すれば、常に (1 , 1) に設定されることになります

デフォルトは、画像を繰り返す GL_REPEAT が設定されています
テクスチャ座標を常に固定するには GL_CLAMP を指定すればよいでしょう
#include <windows.h>
#include <GL/gl.h>
#include <GL/glut.h>

#define TEXSIZE 64

GLubyte pixels[TEXSIZE][TEXSIZE][3];
GLuint texName;

void disp( void ) {
	glClear(GL_COLOR_BUFFER_BIT);
	glBindTexture(GL_TEXTURE_2D , texName);

	glBegin(GL_POLYGON);
		glTexCoord2f(0 , 0); glVertex2f(-0.9 , -0.9);
		glTexCoord2f(0 , 2); glVertex2f(-0.9 , 0.9);
		glTexCoord2f(2 , 2); glVertex2f(0.9 , 0.9);
		glTexCoord2f(2 , 0); glVertex2f(0.9 , -0.9);
	glEnd();
	glFlush();
}

int main(int argc , char ** argv) {
	unsigned int i , j;

	for (i = 0 ; i < TEXSIZE ; i++) {
		int r = (i * 0xFF) / TEXSIZE;
		for (j = 0 ; j < TEXSIZE ; j++) {
			pixels[i][j][0] = (GLubyte)r;
			pixels[i][j][1] = (GLubyte)(( j * 0xFF ) / TEXSIZE);
			pixels[i][j][2] = (GLubyte)~r;
		}
	}

	glutInit(&argc , argv);
	glutInitWindowSize(400 , 300);
	glutInitDisplayMode(GLUT_SINGLE | GLUT_RGBA | GLUT_DEPTH);
	
	glutCreateWindow("Kitty on your lap");
	glutDisplayFunc(disp);

	glEnable(GL_TEXTURE_2D);
	glGenTextures(1 , &texName);
	glBindTexture(GL_TEXTURE_2D , texName);
	glTexParameteri(GL_TEXTURE_2D , GL_TEXTURE_WRAP_S , GL_CLAMP);
	glTexParameteri(GL_TEXTURE_2D , GL_TEXTURE_WRAP_T , GL_CLAMP);

	glTexImage2D(
		GL_TEXTURE_2D , 0 , 3 , TEXSIZE , TEXSIZE ,
		0 , GL_RGB , GL_UNSIGNED_BYTE , pixels
	);

	glutMainLoop();

	glDeleteTextures(1 , &texName);
	return 0;
}


このプログラムでは、テクスチャ座標を(2 , 2) まで引き伸ばしていますが
GL_CLAMP を設定しているため (1 , 1) に固定されています



前のページへ戻る次のページへ