常駐テクスチャ


専用メモリにテクスチャを常駐させる

ハードウェアによっては、3次元グラフィックス処理専用の機能を搭載するものもあります
もし、OpenGL が専用のハードウェアを利用できるならば、高速な処理が期待できます

テクスチャ処理を専門とするハードウェアとキャッシュが存在する場合
OpenGL はテクスチャ・オブジェクトを専用メモリに常駐させることができます
この具体的な制御をクライアントソフトウェアが指示することはできませんが
テクスチャの優先度を設定することで効率化を図ることができるでしょう

もちろん、動作環境にテクスチャ・メモリが存在しなければ
高速なキャッシュ領域にテクスチャを常駐させることはできません
テクスチャの優先度は glPrioritizeTextures() 関数で行います
void glPrioritizeTextures(
  GLsizei n,              
  GLuint * textures,      
  GLclampf * priorities   
);
n には、優先度を設定するテクスチャの数を指定します
textures にテクスチャの名前を含む n 数以上の要素を持つ配列を指定します
priorities には、各要素に与える優先度の値を格納する配列へのポインタです

priorities に指定する優先度は 0.0 〜 1.0 までの値です
0 の優先度は最も低く、このテクスチャはほとんど常駐することはありません
逆に 1.0 は最も優先度が高く、優先的に常駐対象となります

優先度が同一のテクスチャがキャッシュの限界で破棄される場合
最後に利用されてからもっとも時間が経過しているテクスチャが選択されます

テクスチャ・オブジェクトが常駐されているかどうかを調べるには
glAreTexturesResident() 関数を使います
GLboolean glAreTexturesResident(
  GLsizei n,               
  GLuint * textures        
  GLboolean * residences   
);
n には、状態を調べるテクスチャの数を指定します
textures にテクスチャ名を格納する配列へのポインタを指定します
配列の各要素の状態が residences に格納されます
residences には、n 個の要素を持つ配列へのポインタを指定してください

配列内のすべてのテクスチャが常駐している場合は GL_TRUE を返します
この関数が GL_TRUE を返す場合、residences は操作されません
そうでなければ、GL_FALSE が返され、常駐されていない要素に対応する
residences の要素が GL_FALSE に設定されます
#include <windows.h>
#include <GL/gl.h>
#include <GL/glut.h>
#include <stdio.h>

#define TEXSIZE 64

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

void disp( void ) {
	GLboolean blState = GL_TRUE;
	glAreTexturesResident(1 , &texName , &blState);
	printf("テクスチャは常駐%s\n" ,
		blState == GL_TRUE ? "しています" : "していません");

	glClear(GL_COLOR_BUFFER_BIT);
	glBindTexture(GL_TEXTURE_2D , texName);

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

int main(int argc , char ** argv) {
	unsigned int i , j;
	GLclampf prioritie = 1.0F;

	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
	);
	glPrioritizeTextures(1 , &texName , &prioritie);

	glutMainLoop();

	glDeleteTextures(1 , &texName);
	return 0;
}
このプログラムを実行すると、テクスチャの状態が標準出力に表示されます
glPrioritizeTextures() を使って優先順位を最高の 1 に設定しているので
テクスチャ・メモリを実装したシステムであれば、常駐されることでしょう

ただし、テクスチャ・オブジェクトが使われるまではロードされません
テクスチャをバインドしなければ、常駐は保障されません



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