2010年4月20日火曜日

OpenGLでテクスチャ表示

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

#include <gl/glut.h>

//頂点座標
float vertices[][2] =
{
   {-0.5f,  0.5f},
   {-0.5f, -0.5f},
   {0.5f, -0.5f},
   {0.5f,  0.5f},
};

//uv(st)座標
float uvs[][2] =
{
   {0.f, 1.f},
   {0.f, 0.f},
   {1.f, 0.f},
   {1.f, 1.f},
};

//テクスチャハンドル
GLuint hTextures[1];
const unsigned TEXSIZE = 64;

//画素バッファ
GLubyte texImage[TEXSIZE][TEXSIZE][4];

//アイドル時にも画面は更新する
void Idle()
{
   glutPostRedisplay();
}

//描画関数
void Display()
{
   glClear(GL_COLOR_BUFFER_BIT);
   glEnable(GL_TEXTURE_2D);
   glBindTexture(GL_TEXTURE_2D, hTextures[0]);

   //反時計回りに板ポリを描画
   glBegin(GL_QUADS);
   {
      glVertex2fv(vertices[0]); glTexCoord2fv(uvs[0]);
      glVertex2fv(vertices[1]); glTexCoord2fv(uvs[1]);
      glVertex2fv(vertices[2]); glTexCoord2fv(uvs[2]);
      glVertex2fv(vertices[3]); glTexCoord2fv(uvs[3]);
   }

   glEnd();
   glBindTexture(GL_TEXTURE_2D, 0);

   glDisable(GL_TEXTURE_2D);
   glutSwapBuffers();
}

//テクスチャ初期化
void InitTexture()
{
   //テクスチャを1枚生成する
   glGenTextures(1, hTextures);

   //今回は計算でテクスチャを作る
   for(unsigned y=0; y<TEXSIZE; ++y)
   {
      int yy = y / 8;
      for(unsigned x=0; x<TEXSIZE; ++x)
      {
         int xx = x / 8;
         int col = ((yy+xx)&1)*255;

         texImage[y][x][0] = col; //r
         texImage[y][x][1] = 0;   //g
         texImage[y][x][2] = ~col;//b
         texImage[y][x][3] = 0xff;//a
      }
   }

   glPixelStorei(GL_UNPACK_ALIGNMENT, 4);

   //hTexures[0]の設定をここから行うという宣言
   glBindTexture(GL_TEXTURE_2D, hTextures[0]);

   //VRAMにイメージを転送
   glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, TEXSIZE, TEXSIZE, 0, GL_RGBA, GL_UNSIGNED_BYTE, texImage);

   //テクスチャマッピング方式。今回は繰り返しなし
   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);

   //補完フィルタ設定。市松模様なのでnearestでおk
   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);

   //ポリゴンカラーとの混色設定
   glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);

   //hTexures[0]の設定終了
   glBindTexture(GL_TEXTURE_2D, 0);
}

//エントリポイント
int main(int argc, char **argv)
{
   //お決まりの処理
   glutInit(&argc, argv);
   glutInitDisplayMode(GLUT_DOUBLE| GLUT_RGBA);
   glutCreateWindow("DrawTexture");
   glutDisplayFunc(Display);
   glutIdleFunc(Idle);

   glClearColor(0,0,0,1);
   InitTexture();

   //メインループに入る
   glutMainLoop();

   //終了処理
   glDeleteTextures(1, hTextures);
   return 0;
}
テクスチャを表示するだけでこの面倒さ。実際にはBMPなどの画像を読み込む処理も要りますから、これからが大変ですな・・・。あと、3次元配列を最初から用意しておくのもどうかと思うので、こいつをクラス化したりもしました。この辺はまたあとで。

0 件のコメント:

コメントを投稿