OpenGLを使ってみる。その3 -テクスチャ-

terragenで生成した画像です。

サンプル


OpenGLには画像をロードするための関数が用意されていません。
そのため、自力でロードするか、既存のライブラリを利用することになります。

何を使うか迷ったのですが、プラットフォームはwindows以外考えていないので、
GDI+を使ってみたいと思います。

GDI+

必要なヘッダ、ライブラリ
  • gdiplus.h
  • gdiplus.lib
#include <gdiplus.h>
#pragma comment( lib, "gdiplus.lib" )

VC++で自動生成されたプリコンパイル済みヘッダstdafx.hにWIN32_LEAN_AND_MEANが含まれる場合、gdiplus.hをインクルードするとコンパイルエラーになるので、コメントアウトします。

stdafx.h
//#define WIN32_LEAN_AND_MEAN // Windows ヘッダーから使用されていない部分を除外します。

GDI+の初期化

  • GdiplusStartup
  • GdiplusShutdown
ULONG_PTR token;

    //
    //GDI+初期化
    //
    Gdiplus::GdiplusStartupInput input;
    Gdiplus::GdiplusStartup( &token, &input, 0 );

    /*...*/

    //
    //GDI+破棄
    //
    Gdiplus::GdiplusShutdown( token );

画像のロード

Gdiplus::Bitmap bmp( L"ファイル名" );

ピクセルへのアクセス

  • Gdiplus::BitmapDataクラス
    • Gdiplus::BitmapData::Scan0:ピクセルの先頭を指すポインタ
  • Gdiplus::Bitmap::LockBitsメソッド
  • Gdiplus::Bitmap::UnlockBitsメソッド
    Gdiplus::BitmapData data;
    bmp.LockBits( 0, Gdiplus::ImageLockModeRead, PixelFormat32bppARGB, &data );

    //テクスチャ生成
    /*...*/

    bmp.UnlockBits( &data );

テクスチャの生成

  • テクスチャは整数値で管理
  • glGenTextures
  • glBindTexture
  • glTexImage2D
  • glDeleteTextures
  • glTexParameterf
    • GL_TEXTURE_MIN_FILTER
    • GL_TEXTURE_MAG_FILTER
    • GL_TEXTURE_WRAP_S
    • GL_TEXTURE_WRAP_T
GLuint texture;
    //
    //画像のロード
    //
    Gdiplus::Bitmap bmp( L"ファイル名" );
    //
    //画像のピクセルを取得
    //
    Gdiplus::BitmapData data;
    bmp.LockBits( 0, Gdiplus::ImageLockModeRead, PixelFormat32bppARGB, &data );
    //
    //テクスチャの生成
    //
    glGenTextures( 1, &texture );
    glBindTexture( GL_TEXTURE_2D, texture );
    glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
    glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
    glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
    glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
    //
    //テクスチャにピクセルを書き込む
    //
    glTexImage2D( GL_TEXTURE_2D,
        0, GL_RGBA, data.Width, data.Height, 0, GL_BGRA_EXT, GL_UNSIGNED_BYTE, data.Scan0 );
    //
    //後始末
    //
    glBindTexture( GL_TEXTURE_2D, 0 );
    bmp.UnlockBits( &data );
    glDeleteTextures( 1, &texture );

描画

  • glTexCoord2f
    glBindTexture( GL_TEXTURE_2D, texture );
    glBegin( GL_QUADS );
        glColor4f( 1.0f, 1.0f, 1.0f, 1.0f );
        glTexCoord2f( 0.0f, 0.0f );
        glVertex3f( 0.0f, 0.0f, 0.0f );
        glTexCoord2f( 1.0f, 0.0f );
        glVertex3f( 256.0f, 0.0f, 0.0f );
        glTexCoord2f( 1.0f, 1.0f );
        glVertex3f( 256.0f, 256.0f, 0.0f );
        glTexCoord2f( 0.0f, 1.0f );
        glVertex3f( 0.0f, 256.0f, 0.0f );
    glEnd();