PNG画像の一部をストレッチ描画する(LodePNG)

PNG画像を読み込んで画像の一部をストレッチ描画します。
http://members.gamedev.net/lode/projects/LodePNG/
に、ある LodePNGモジュールを使用します。
*(現在の最新版では引数などが変わっているようですので設定の仕方のページから
当サイトで使用しているバージョンをインストールして下さい。)
このLodePNGは.cppファイルと.hファイルのみで構成されているので手軽に組み込めます。
zlib も libpng も何も使わずに.cppソースのみでPNG画像が読み込めます。
また、LodePNGは、どのように使ってもよいそうです。再配布も可能です。
作者への連絡も必要ないそうです。素晴らしいですね。
使い方も簡単で LodePNG_loadFile で読み込んで LodePNG_decode で、デコード
します。
画像の一部を断片的に描画するようにするにはST座標(DirectXではUV座標)を指定して
あげれば良いです。
『画像を表示する』のチュートリアルでは、glTexCoord2f(0.0f, 0.0f); で指定していました。
これだと、0.0~1.0の範囲で記述しなければならないので解りにくいです。
ピクセル単位で指定するには、拡張機能の GL_TEXTURE_RECTANGLE_EXT を使います。
GL_TEXTURE_RECTANGLE_EXT を使うと glTexCoord2i(x,y); でピクセル単位で
ST座標を指定する事ができるようになります。
拡張機能を使うには OpenGL SDK の glext.h その他が必要になります。
『設定の仕方』を参考にインストールしてください。

下の画像は、maptip.png の一部を描画しています。

 

ファイル
main.cpp
lodepng.cpp
lodepng.h

maptip.png

main.cpp

#pragma comment(linker, "/SUBSYSTEM:WINDOWS /ENTRY:mainCRTStartup")
#include <gl/glew.h>
#include <GL/freeglut/freeglut.h>
#include <stdio.h>
#include "lodepng.h"

#define WIDTH 320
#define HEIGHT 240

//サイズ用構造体
struct SizeRECT{
 int x;
 int y;
 int width;
 int height;
};

GLuint texture;
//サイズセット
void SetSizeRECT(SizeRECT* rect, int a,int b,int c,int d)
{
 rect->x=a;rect->y=b;rect->width=c;rect->height=d;
}
//ストレッチ描画
void DrawStretch(SizeRECT Dst,SizeRECT Src)
{
 glEnable( GL_TEXTURE_RECTANGLE_EXT );//拡張機能を使う
 glBindTexture( GL_TEXTURE_RECTANGLE_EXT, texture );

    glEnable(GL_ALPHA_TEST);//アルファテスト開始
    glBegin(GL_POLYGON);
  glTexCoord2i(Src.x, Src.y+Src.height);   glVertex2d(Dst.x , Dst.y+Dst.height);//左下
  glTexCoord2i(Src.x, Src.y);      glVertex2d(Dst.x ,  Dst.y);//左上
  glTexCoord2i(Src.x+Src.width, Src.y);    glVertex2d( Dst.x+Dst.width ,  Dst.y);//右上
  glTexCoord2i(Src.x+Src.width, Src.y+Src.height);glVertex2d( Dst.x+Dst.width , Dst.y+Dst.height);//右下
    glEnd();
    glDisable(GL_ALPHA_TEST);//アルファテスト終了
 glDisable( GL_TEXTURE_RECTANGLE_EXT );
}
void display(void)
{
 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
 glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
 glOrtho(0.0, WIDTH, HEIGHT, 0.0, -1.0, 1.0);

 glEnable(GL_TEXTURE_2D);//テクスチャ有効

 SizeRECT Dst,Src;
 //城
 SetSizeRECT(&Dst,50,50,128,128);
 SetSizeRECT(&Src,80,160,48,48);
 DrawStretch(Dst,Src);
 //林
 SetSizeRECT(&Dst,10,10,32,32);
 SetSizeRECT(&Src,0,80,16,16);
 DrawStretch(Dst,Src);

 glDisable(GL_TEXTURE_2D);//テクスチャ無効

 glutSwapBuffers();
}
void idle(void)
{
 glutPostRedisplay();
}
void Init(){
 glClearColor(0.0, 0.0, 0.0, 1.0);
 glOrtho(0, WIDTH, HEIGHT, 0, -1, 1);

 LodePNG_Decoder decoder;
 LodePNG_Decoder_init(&decoder);
 unsigned char* buffer;
 unsigned char* image;
 size_t buffersize, imagesize;
 //ロード
 LodePNG_loadFile(&buffer, &buffersize, "maptip.png");
 //デコード
 LodePNG_decode(&decoder, &image, &imagesize, buffer, buffersize);
 //幅,高さ
 int width = decoder.infoPng.width; int height = decoder.infoPng.height;

 glGenTextures(1, (GLuint *)&texture);
 
 glBindTexture(GL_TEXTURE_2D, texture);
 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); 

 glEnable( GL_TEXTURE_RECTANGLE_EXT );//拡張機能を使う
 glBindTexture( GL_TEXTURE_RECTANGLE_EXT, texture );
 glTexImage2D(GL_TEXTURE_RECTANGLE_EXT, 0, GL_RGBA,width, height, 0,GL_RGBA, GL_UNSIGNED_BYTE, image);
 glDisable( GL_TEXTURE_RECTANGLE_EXT );

}
int main(int argc, char *argv[])
{
 glutInitWindowPosition(100, 100);
 glutInitWindowSize(WIDTH, HEIGHT);
 glutInit(&argc, argv);
 glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);
 glutCreateWindow("画像の切り抜きとストレッチ");
 glutDisplayFunc(display);
 glutIdleFunc(idle);
 Init();
 glutMainLoop();
 return 0;
}

 

 

 

 

 

 

 

最終更新:2015年01月02日 23:54