5.画像表示基礎
今までのプログラムでは,ppm ファイルを書き出して,それを画像ビューワーで見て確認するという作業をしていました.ここでは画像を見るためのソフトの作り方を勉強します.画像の表示なんて難しそうだ…と思う必要は全くありません.OpenGLという開発者にとって強い味方がいるからです.
OpenGLは Open Graphics Library の名の通り,画像表示のためのライブラリです.画像表示のための関数群が用意されているので,それを使うと簡単に画像表示のプログラムを書くことができます.ここでは,GLUTというOpenGLを使うためのツールキットがあるので,それを使います.LinuxやWindowsなどOSによらずにプログラムの互換性があるため,とても便利です.
OpenGLに関しては,たくさん良いページが書かれているので,それを使って勉強しましょう.一番勉強に適しているのはこのページだと思います.
◎ GLUTによる「手抜き」OpenGL入門 (和歌山大学 床井先生)
演習5−1
演習5−1ですっかりOpenGLに関しては理解できたと思いますが,少しだけ追加の演習をやっておきます.下のプログラムは640×480の画像を見るための画像ビューワーです.しかも1秒ごとにポジとネガが反転します.
今まではプログラム上でファイル名を指定していましたが,main() を int main(int argc, char *argv[]) とすることによって,標準入力やドラッグアンドドロップしたファイル名を取り出すように拡張しています.
#include "glut.h" unsigned char image[480][640][3]; //取り込む画像 void display(void){ // 画像の描画 glClear(GL_COLOR_BUFFER_BIT); glRasterPos2f(-1 , 1); //ずらして glDrawPixels(640, 480, GL_RGB, GL_UNSIGNED_BYTE, &image[0][0][0]); //画像を貼る glFlush(); //実行されていない OpenGL の命令を全部実行 } void keyboard(unsigned char key, int x, int y){ //キーボードの処理 switch(key){ case 'q': case 'Q': case '\033': exit(0); //終了 } } void init(void){ //初期化 glClearColor(1.0, 1.0, 1.0, 1.0); } void idle(void){ //アイドル状態の時に再描画 glutPostRedisplay(); //描画 } void timer(int value){ //タイマー int x, y; for( y=0; y<480;y++){ for(x=0;x<640;x++){ //ポジとネガを反転する image[y][x][0] = 0xff - image[y][x][0]; image[y][x][1] = 0xff - image[y][x][1]; image[y][x][2] = 0xff - image[y][x][2]; }} glutTimerFunc(1000,timer,0); //タイマー ミリ秒毎に呼ばれる } int main(int argc, char *argv[]){ int i,x,y; printf("argc = %d\n",argc); for( i = 0 ; i < argc ; i++) printf("argv[%d] = %s\n",i,argv[i]); if( argc == 2) ppm_read(argv[1],&image[0][0][0]); //ファイルを開く else{//日の丸を作る for( y=0 ; y<480 ; y++){ for( x=0 ; x<640 ; x++){ if( (y-240)*(y-240) + (x-320)*(x-320) < 80*80 ){ image[y][x][0] = 0xff; image[y][x][1] = image[y][x][2] = 0x00; //赤 } else image[y][x][0] = image[y][x][1] = image[y][x][2] = 0xff; //白 }} } glutInit(&argc, argv); //GLUT および OpenGL 環境を初期化 glutInitWindowSize(640, 480); //窓の大きさ glutInitDisplayMode(GLUT_RGBA); //ディスプレイ表示モードの設定 glutCreateWindow(argv[0]); //ウィンドウを開く glutDisplayFunc(display); //再描画 glPixelZoom(1, -1); //OpenGL の座標系の上下を反対に glutKeyboardFunc(keyboard); //キーボードの処理 init(); //初期化 glutIdleFunc(idle); //アイドル状態の時に処理する glutTimerFunc(1000,timer,0); //タイマー ミリ秒毎に呼ばれる glutMainLoop(); //無限ループ return 0; } |
int main(int argc, char *argv[]) に関してもう少し詳しく説明しておきましょう.linuxの場合,mule file.txt のようにコマンドを打ってファイルを開くことが多いと思います.Windowsの場合は,file.doc というファイルをダブルクリックしたり,ワードのアイコンにドラッグアンドドロップ(重ねたり)して開けることでしょう.
test.exe という実行ファイルがあった時に,./test.exe file.txt とコマンドを打つのと,file.txt を test.exe にドラッグアンドドロップするのと,txt ファイルを test.exe に対応付けて file.txt をダブルクリックするのは,プログラム的にはすべて同じことを表しており,この場合 argc と argv には
argc = 2,argv[0] = "test.exe",argv[1] = "file.txt"
が代入されます.上のプログラムを打って,コマンドラインで ppm を開くか,Windowsの場合は実行ファイルに ppm ファイルをドラッグアンドドロップしてみよう.下図左のような画面が表示されるはずです.また,単体で立ち上げてみよう(日の丸が表示されます).それらの時にコマンドプロンプトに表示される文字列を見比べると,理解できると思います.
演習5−2
3次元表示に関しても,演習5−1でマスターできていると思います.そのうちステレオ処理の課題を作るつもりですので,それが完成してから,3次元表示のおさらいをすることにしましょう.
いつになるかは分かりませんので…期待せずに待っていてください…