2010年4月20日火曜日

OpenGLでテクスチャ表示

楽勝だと思っていたが意外と苦労した。アラインメントや配列について学びなおすいい機会だったと思う。とりあえず、テクスチャを表示するだけコードを載せてみよう。

001#include <gl/glut.h>
002 
003//頂点座標
004float vertices[][2] =
005{
006   {-0.5f,  0.5f},
007   {-0.5f, -0.5f},
008   {0.5f, -0.5f},
009   {0.5f,  0.5f},
010};
011 
012//uv(st)座標
013float uvs[][2] =
014{
015   {0.f, 1.f},
016   {0.f, 0.f},
017   {1.f, 0.f},
018   {1.f, 1.f},
019};
020 
021//テクスチャハンドル
022GLuint hTextures[1];
023const unsigned TEXSIZE = 64;
024 
025//画素バッファ
026GLubyte texImage[TEXSIZE][TEXSIZE][4];
027 
028//アイドル時にも画面は更新する
029void Idle()
030{
031   glutPostRedisplay();
032}
033 
034//描画関数
035void Display()
036{
037   glClear(GL_COLOR_BUFFER_BIT);
038   glEnable(GL_TEXTURE_2D);
039   glBindTexture(GL_TEXTURE_2D, hTextures[0]);
040 
041   //反時計回りに板ポリを描画
042   glBegin(GL_QUADS);
043   {
044      glVertex2fv(vertices[0]); glTexCoord2fv(uvs[0]);
045      glVertex2fv(vertices[1]); glTexCoord2fv(uvs[1]);
046      glVertex2fv(vertices[2]); glTexCoord2fv(uvs[2]);
047      glVertex2fv(vertices[3]); glTexCoord2fv(uvs[3]);
048   }
049 
050   glEnd();
051   glBindTexture(GL_TEXTURE_2D, 0);
052 
053   glDisable(GL_TEXTURE_2D);
054   glutSwapBuffers();
055}
056 
057//テクスチャ初期化
058void InitTexture()
059{
060   //テクスチャを1枚生成する
061   glGenTextures(1, hTextures);
062 
063   //今回は計算でテクスチャを作る
064   for(unsigned y=0; y<TEXSIZE; ++y)
065   {
066      int yy = y / 8;
067      for(unsigned x=0; x<TEXSIZE; ++x)
068      {
069         int xx = x / 8;
070         int col = ((yy+xx)&1)*255;
071 
072         texImage[y][x][0] = col; //r
073         texImage[y][x][1] = 0;   //g
074         texImage[y][x][2] = ~col;//b
075         texImage[y][x][3] = 0xff;//a
076      }
077   }
078 
079   glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
080 
081   //hTexures[0]の設定をここから行うという宣言
082   glBindTexture(GL_TEXTURE_2D, hTextures[0]);
083 
084   //VRAMにイメージを転送
085   glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, TEXSIZE, TEXSIZE, 0, GL_RGBA, GL_UNSIGNED_BYTE, texImage);
086 
087   //テクスチャマッピング方式。今回は繰り返しなし
088   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
089   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
090 
091   //補完フィルタ設定。市松模様なのでnearestでおk
092   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
093   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
094 
095   //ポリゴンカラーとの混色設定
096   glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
097 
098   //hTexures[0]の設定終了
099   glBindTexture(GL_TEXTURE_2D, 0);
100}
101 
102//エントリポイント
103int main(int argc, char **argv)
104{
105   //お決まりの処理
106   glutInit(&argc, argv);
107   glutInitDisplayMode(GLUT_DOUBLE| GLUT_RGBA);
108   glutCreateWindow("DrawTexture");
109   glutDisplayFunc(Display);
110   glutIdleFunc(Idle);
111 
112   glClearColor(0,0,0,1);
113   InitTexture();
114 
115   //メインループに入る
116   glutMainLoop();
117 
118   //終了処理
119   glDeleteTextures(1, hTextures);
120   return 0;
121}
テクスチャを表示するだけでこの面倒さ。実際にはBMPなどの画像を読み込む処理も要りますから、これからが大変ですな・・・。あと、3次元配列を最初から用意しておくのもどうかと思うので、こいつをクラス化したりもしました。この辺はまたあとで。

0 件のコメント:

コメントを投稿