[OpenGL] 画像をテクスチャで使う

LINEで送る
Pocket

OpenGLでは画像をテクスチャとしてマッピングする事が多々あるとは思うのですが、やり方を残しておきます。

なお、これはC++のプロジェクトを使った場合で、Cocoaは使えない状況を想定しています。

画像の読み込み

画像の読み込みには、OpenCVを使いました。ただし、IplImageはRGBではなく、BGRの順番で色データを格納しているので注意が必要です。

 // IplImageとして画像をロード
 IplImage* image = cvLoadImage("/events/mo1.png");
    
    int w = image->width;
    int h = image->height;
    int channels = image->nChannels;
    
    GLubyte* imageData = (GLubyte*)malloc(w*h*channels);
    
    for(int i = 0; i < w*h*channels; i+=channels)
    {
        imageData[i] = image->imageData[i+2];        // R
        imageData[i+1] = image->imageData[i+1];   // G
        imageData[i+2] = image->imageData[i];       //  B
        if(channels > 3)
        {
            imageData[i+3] = image->imageData[i+3]; // Aが存在する場合
        }
    }

以上で画像データをOpenGLで使える形式に読み込む事ができました。
次に、テキスチャとしてバインドします。

 // テキスチャの生成
    glGenTextures(1, &g_imageTex);
    // テキスチャと変数をバインド(関連付け)
    glBindTexture(GL_TEXTURE_2D, g_imageTex);
    // 各種フィルタの設定
    glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
    
    // 実際のテキスチャを設定
    glTexImage2D(GL_TEXTURE_2D, // テキスチャの種類。
                 0,             // level: 解像度が単一の場合は0
                 GL_RGB,       // どの成分が画像のテクセルに使用されているか
                 w, h,          // サイズ
                 0,             // border: 境界の幅
                 GL_RGB,       // 描画フォーマット
                 GL_UNSIGNED_BYTE, // データの型
                 imageData          // 実際のデータ
    );
 

実際にテキスチャを表示させる処理。(display関数内部)

glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
    glEnable(GL_TEXTURE_2D);
    
    glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
    //glBindTexture(GL_TEXTURE_2D, texName);
    glBindTexture(GL_TEXTURE_2D, g_imageTex);
    
    glBegin(GL_QUADS);
    // OpenGLの座標とテキスチャの座標をマッピングする
    glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f,  1.0f, 0.0f);
    glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, -1.0f, 0.0f);
    glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, -1.0f, 0.0f);
    glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f,  1.0f, 0.0f);
    
    
    glEnd();
    
    glFlush();
    
    glDisable(GL_TEXTURE_2D);

MacでGLUTを使用する

LINEで送る
Pocket

最近OpenGLで描画するものを作る事が結構増えてきたのですが、割とプリミティブな形状を描画するばかりでした。

だけどこのままじゃだめで、もっと深く突っ込みたくなったので基礎から始める事にしました。

今回はMac上(Mac OS X 10.6 Snow Leopard)でglutを使って開発する時のひな形となるものを残しておきます。

#include
#include

void init(void)
{
// 領域の色をクリアする
glClearColor(0.0, 0.0, 0.0, 0.0);

}

void display(void)
{
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);

// 描画の処理を書く

// バッファをクリアして実際に描画させる
glFlush();

}

void keyboard(unsigned char key, int x, int y)
{
// キー操作時の処理を書く

// 再描画
glutPostRedisplay();
}

void reshape(int w, int h)
{
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
// glOrthoなどを使ってリサイズ設定をする
.
.
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}

int main (int argc, const char * argv[])
{

// GLUTを初期化
glutInit(&argc, (char**)argv);
//
glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGB|GLUT_DEPTH);
// ウィンドウ位置、ウィンドウサイズを設定
glutInitWindowPosition(0, 0); glutInitWindowSize(640, 480);
// windowを作成
int mwin = glutCreateWindow("window");

init();
// 描画ループにおいて呼ばれる
glutDisplayFunc(display);
// ウィンドウサイズ・描画領域のサイズ変更時に呼ばれる
glutReshapeFunc(reshape);
// キー操作を扱う
glutKeyboardFunc(keyboard);
// 描画ループを開始する
glutMainLoop();

return 0;
}