OpenGLで画像をテクスチャとして面に貼り付けるには、画像の縦横のサイズが2のべき乗数でなければならないという制約があります。
OpenGLの関数にそのように画像をリサンプルする関数(gluScaleImage()
)があるのですが、
大きな画像を分割したいときなんかはこの方法を使ったほうがいいでしょう。
以下の例は、画像を下図のように分割する例です。
/* ビットマップをIMG_SIZE×IMG_SIZEのタイルに分割してそれぞれファイルに保存する */ void CreateTile ( BYTE *btImg, int iInX, int iInY, int *piOutX, int *piOutY, int iSamplePerPixel, int *piRowTileNum, int *piColTileNum, BYTE ***pOutImg ) { int iTotalWidth, iTotalHeight; int i, j, k, l, m, x = 0, y = 0, nPix, nRow; int iCol, iRow; LPSTR pInputBit, pImage, pImageBit; //全体の画像サイズ(IMG_SIZEの倍数)を求める iTotalWidth = IMG_SIZE * (int)(ceil(iInX/IMG_SIZE)); iTotalHeight = IMG_SIZE * (int)(ceil(iInY/IMG_SIZE)); //縦横の分割数を計算する、上限はIMG_SIZE iColTileNum = (int)(iTotalWidth / IMG_SIZE)+1; iRowTileNum = (int)(iTotalHeight / IMG_SIZE)+1; if ( !iRowTileNum ) iRowTileNum = 1; if ( !iColTileNum ) iColTileNum = 1; //分割画像の数分のポインタを取得する *OutImg = new BYTE*[iRowTileNum * iColTileNum]; //ここで、2^nの領域を取得しておく for ( i = 0; i < iRowTileNum * iColTileNum; i++ ) { (*pOutImg)[i] = new BYTE[IMG_SIZE*IMG_SIZE*iSamplePerPixel]; } iCol = iColTileNum; iRow = iRowTileNum; //画像の縦横どちらかがIMG_SIZEを下回ったらファイル分割終了 while ( (iTotalWidth / nSkip) >= IMG_SIZE || (iTotalHeight / nSkip) >= IMG_SIZE ) { //左下の画像からコピー、 for ( i = 0; i < iRow; i++ ) { //最後のタイル行かどうかで半端かIMG_SIZEかが決まる i == iRow - 1 ? nRow = iInY % (IMG_SIZE*nSkip) : nRow = (IMG_SIZE*nSkip); for ( j = 0; j < iCol; j++ ) { //出力用画像マトリックスの全ピクセルを0xFFにセット pImageBit = pImage; memset( pImage, 0xFF, IMG_SIZE*IMG_SIZE*iSamplePerPixel*sizeof(BYTE) ); //現在のタイルの先頭にpBitをセット pInputBit = btImg; pInputBit += IMG_SIZE*(iInX*iSamplePerPixel)*i + IMG_SIZE*nSkip*iSamplePerPixel*j; //最後のタイル列かどうかでコピーする幅を設定 j == iCol-1 ? nPix = iInX % IMG_SIZE : nPix = IMG_SIZE; //1行ずつコピー for ( k = 0; k < nRow; k += nSkip ) { //一列ずつコピー for ( l = 0; l < nPix; l += nSkip ) { //ピクセルごとにコピー for ( m = 0; m < iSamplePerPixel; m++ ) { (*pOutImg)[i*nCol+j][y*IMG_SIZE*iSamplePerPixel+x*iSamplePerPixel+m] = = pInputBit[l*iSamplePerPixel+m]; } x++; } y++; x = 0; pInputBit += iInX*iSamplePerPixel; } y = 0; } } } *piOutX = iTotalWidth; *piOutY = iTotalHeight; *piRowTileNum = iRowTileNum; *piColTileNum = iColTileNum; }