平成 20kuni/enshu2008/enshu2008_1027.pdf1 平成20 年度機械情報工学科演習...

22
1 20 コンピュータグラフィクス (2) OpenGL+GUI(GLUI) による 3DCG テクスチャマッピング TA:伊 2008 10 27 1 演習の目的 OpenGL に,OpenGL GUI わせを学 ため,GLUI たプログラミングを う.さらに, グラフィックス をより にするライティング,テクス チャマッピングについて学 をする. 1.1 資料など http://www.cyber.t.u-tokyo.ac.jp/~kuni/enshu2008/ においてある. するソースファイル からダ ンロードするこ したい 1.2 出席・課題の確認について によって う. 題が したら, 員・TA び, って して せよ. 1.3 「メディアインタフェース」について 「メディアインタフェース」 2008/12/4( ) に,EyeToy するこ

Upload: others

Post on 12-Nov-2020

2 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: 平成 20kuni/enshu2008/enshu2008_1027.pdf1 平成20 年度機械情報工学科演習 コンピュータグラフィクス(2) OpenGL+GUI(GLUI) による3DCG の応用 テクスチャマッピング

1

平成 20年度 機械情報工学科演習

コンピュータグラフィクス (2)

OpenGL+GUI(GLUI)による 3DCGの応用

テクスチャマッピング

担当:谷川 智洋 講師,西村 邦裕 助教,中垣 好之 技官TA:伊東 里香,今井 智章,加倉井 健人

2008年 10月 27日

1 演習の目的

本日の演習では,前回 OpenGLの基礎を元に,OpenGLと GUIと組み合わせを学ぶため,GLUIを用い

たプログラミングを行う.さらに,三次元グラフィックスの表示をより高品質にするライティング,テクス

チャマッピングについて学習をする.

1.1 資料など

本日の演習の資料などは,¶ ³http://www.cyber.t.u-tokyo.ac.jp/~kuni/enshu2008/µ ´

においてある.

本日使用するソースファイルも同じ場所からダウンロードすること.前回の資料を参照したい場合も同じ場

所を参照のこと.

1.2 出席・課題の確認について

出席の確認は,課題の確認によって行う.課題が終了したら,教員・TAを呼び,指示に従って実行して説

明せよ.

1.3 「メディアインタフェース」について

次回の「メディアインタフェース」の演習 2008/12/4(木)の際に,EyeToyを持参すること.

Page 2: 平成 20kuni/enshu2008/enshu2008_1027.pdf1 平成20 年度機械情報工学科演習 コンピュータグラフィクス(2) OpenGL+GUI(GLUI) による3DCG の応用 テクスチャマッピング

2 2 GLUI

2 GLUI

2.1 GLUIとは

GLUI とは,OpenGL で利用可能な簡単なウィジェットライブラリである.以下のような特徴がある.

• OpenGL および glut にのみ依存するため,移植性が高い.OpenGL と glut が動作する C++ の環境

であれば,基本的に同じソースコードが動作する.具体的には Linux, Windows (Visual C++, gcc),

Macintosh などで利用可能である.

• glut から自然に移行可能である. glut のソースを大きく変更することなく,ソースに追加していく形

で GUI を作成できる.つまりマウスやキーボード,再描画などのイベント(コールバック関数の取り

扱いやウィンドウの作成)などほぼ全ての glutの関数がそのまま有効であり,利用可能である.

• GUI のデザインが簡単である. ソースコードの記述順に,ボタンやチェックボックスなどの部品が自

動的に(左上から)配置されるため,別途,部品を配置するためのファイルやデータの作成,また専用

のデザインツールなどが必要ない.

• 研究活動に向いた機能主体である.立体的な CGを様々な視点から観察する際に便利な,3次元的な回

転や平行移動のための専用の部品を持つ.これを利用すると,直接 glMultMatrix() で利用可能な行列

が与えられるため,クォータニオンなどを知らなくても対象の回転が簡単に出来る.

• テキスト入力もできる.glutでは右クリックによるメニュー程度しかないが,gluiを使えばファイル名

などのテキストを入力させるなどもスマートに組み込める.gluiではボタンなどが配置できるので,メ

ニューの表示などにより,開発者以外にもにわかりやすいプログラムを作ることができる.

図 1 GLUIによる表示の例(左側の設定ウィンドウ)

反面,単純さゆえに以下のような欠点がある.ただし,研究で用いる簡単なプログラムには十分である.

• 凝ったデザインが難しい. ソースコードの記述順にボタン等が並ぶだけであるため,自由に部品を配置することが難しい.また,ボタンにアイコンなどの絵を重ねて表示することなどができない.

• 部品の種類が少ない. ウィンドウ端のスクロールバーや,連続値を入力するスライドバーなどが用意されていない.

Page 3: 平成 20kuni/enshu2008/enshu2008_1027.pdf1 平成20 年度機械情報工学科演習 コンピュータグラフィクス(2) OpenGL+GUI(GLUI) による3DCG の応用 テクスチャマッピング

2.1 GLUIとは 3

2.1.1 GLUIの概要

GLUIには,以下のような部品が用意されている.

ボタン (Buttons) クリックすることができる押しボタンスイッチ.

チェックボックス (Checkboxes) チェックの ON・OFF.

ラジオボタン (Radio Buttons) グループ内のどれか1つにチェックを入れる.

テキストボックス (Editable Text Boxes) ユーザが文字を入力できる白い空白部分.その左側に説明を表示

することが可能.

スピナー (Spinners) 上下ボタンで数値が変えられ,数値の部分に直接キーボードから数値を入れることも

可能.

リストボックス (Listboxes) 画面中央上にあるように複数の選択肢から1つを選ぶ.ラジオボタンよりも選

択肢が多い場合や,選択肢の数が動的に変化する場合に使用.

回転コントロール (Rotation Controls) マウスでドラッグすることにより画面に表示された物体を回転させ

るために用いる.

平行移動コントロール (Translation Controls) 中央下にあるもので,ドラッグすることで対象の平行移動が

できる.

図 2 GLUIの部品一覧

また画面を見やすくしたり,わかりやすくするための以下のような機能もある.

スタティックテキスト (Static Text) 説明文などユーザにより編集しない文字列に使う.プログラム側から

は内容を動的に変更することが可能.

セパレーター (Separators) Static Text の下に引いてあるようなもので,区切りに使う.

カラム (Columns) インタフェースが縦に長くなりすぎると見づらい,適宜右へ折り返すような仕組み.線を

入れることも(左列と中央列の間),入れないことも(中央列と右列の間)可能.

Page 4: 平成 20kuni/enshu2008/enshu2008_1027.pdf1 平成20 年度機械情報工学科演習 コンピュータグラフィクス(2) OpenGL+GUI(GLUI) による3DCG の応用 テクスチャマッピング

4 2 GLUI

パネル (Panels) ひとまとめの機能をくくる四角形.重ねる(入れ子にする)ことができる.

ロールアウト (Rollouts) ボタン部分を押すと折りたたまれるもので,図 2の画面右にあるように最も上のも

のは展開しているが,下2つの部分は畳まれている.

図 3 別ウィンドウとして表示した場合

図 4 ウィンドウ内に表示した場合

glui ではこのようなボタンをメインのウィンドウ(自分のプログラムが表示している部分)とは別のウィン

ドウに出すこともでき(図 3),プログラムの1,2行の変更のみでメインウィンドウの一部に一緒に表示する

こともできる(図 4).

別ウィンドウとして表示した場合¶ ³GLUI *glui = GLUI_Master.create_glui( "GLUI" );µ ´

ウィンドウ内に表示した場合¶ ³GLUI *glui = GLUI_Master.create_glui_subwindow(main_window,

GLUI_SUBWINDOW_BOTTOM);

glui->set_main_gfx_window( main_window );µ ´

Page 5: 平成 20kuni/enshu2008/enshu2008_1027.pdf1 平成20 年度機械情報工学科演習 コンピュータグラフィクス(2) OpenGL+GUI(GLUI) による3DCG の応用 テクスチャマッピング

2.2 glutから GLUI 5

GLUI SUBWINDOW BOTTOM の部分を, GLUI SUBWINDOW TOP に変えるとウィンドウの上部

に, GLUI SUBWINDOW LEFT に変えるとウィンドウの左側に表示される.

2.2 glutから GLUI

最も簡単な teapot を書くだけのプログラムに UIをつけることを考える.プログラムの必要部分のみ提示

する.

#include <stdio.h>

#include <math.h>

#include <GL/glut.h>

void display(void) {

glClear(GL_COLOR_BUFFER_BIT);

glutWireTeapot(1.5);

glutSwapBuffers();

glutPostRedisplay();

}

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

glutInit(&argc, argv);

glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);

glutCreateWindow(argv[0]);

glutDisplayFunc(display);

glClearColor(0.0, 0.0, 1.0, 0.0);

glutMainLoop();

return 0;

}

これに GLUI を使ってティーポットの回転ができるようにし,ついでにボタンを押すと終了する様にする.

#include <stdio.h>

#include <math.h>

#include <GL/glut.h>

#include <glui.h>

Page 6: 平成 20kuni/enshu2008/enshu2008_1027.pdf1 平成20 年度機械情報工学科演習 コンピュータグラフィクス(2) OpenGL+GUI(GLUI) による3DCG の応用 テクスチャマッピング

6 2 GLUI

/*---回転のため---*/

float rotate[16] = {

1,0,0,0,

0,1,0,0,

0,0,1,0,

0,0,0,1

};

void display(void) {

glClear(GL_COLOR_BUFFER_BIT);

/*---回転のため---*/

glPushMatrix();

glMultMatrixf( rotate );

glutWireTeapot(1.5);

glPopMatrix();

/*---回転のため---*/

glutSwapBuffers();

glutPostRedisplay();

}

/*===終了のため===*/

void gluiCallback(int num) {

exit(0);

}

/*===終了のため===*/

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

glutInit(&argc, argv);

glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);

glutCreateWindow(argv[0]);

glutDisplayFunc(display);

glClearColor(0.0, 0.0, 1.0, 0.0);

Page 7: 平成 20kuni/enshu2008/enshu2008_1027.pdf1 平成20 年度機械情報工学科演習 コンピュータグラフィクス(2) OpenGL+GUI(GLUI) による3DCG の応用 テクスチャマッピング

2.3 GLUIのサンプル 7

/*---GLUI initialize---*/

GLUI *glui = GLUI_Master.create_glui("control");

/*---GLUI 回転のため---*/

GLUI_Rotation *view_rot= new GLUI_Rotation(glui, "Rotation",rotate);

/*===GLUI 終了のため===*/

new GLUI_Button(glui, "Exit", 0, gluiCallback);

glutMainLoop();

return 0;

}

図 5 GLUIによる teapotの操作 UI

2.3 GLUIのサンプル

GLUIのサンプルはあらかじめフォルダにいれてある.example1, example2, example3, example4, exam-

ple5を参照のこと.実行するには、bin以下のフォルダを実行し,ソースを見るには、example以下のフォル

ダを参照のこと.¶ ³/usr/local/src/glui-2.35/src/example/

/usr/local/src/glui-2.35/src/bin/µ ´

Page 8: 平成 20kuni/enshu2008/enshu2008_1027.pdf1 平成20 年度機械情報工学科演習 コンピュータグラフィクス(2) OpenGL+GUI(GLUI) による3DCG の応用 テクスチャマッピング

8 2 GLUI

◇ 課題 1 ◇¶ ³1. sample glui.cpp,sample glui teapot.cppおよびMakefileをダウンロードして,実行し,確

認せよ.また,Teapotにチェックボックスをつけて glutWireTeapotと glutSolidTeapotを

変更できるようにせよ.

2. exmple5 などを参考にして,ボタン,回転コントロール,チェックボックス以外の 2つ以上

の部品を上記の Teapotに追加せよ.機能は,Teapotの移動やズーム,サイズの指定など何

でもよい.

3. 前回作成したロボットアームを UIで制御できるようににせよ.(オプション)

µ ´

Page 9: 平成 20kuni/enshu2008/enshu2008_1027.pdf1 平成20 年度機械情報工学科演習 コンピュータグラフィクス(2) OpenGL+GUI(GLUI) による3DCG の応用 テクスチャマッピング

9

3 画像の取り扱い

OpenGLでは,画像において各ピクセルに保存されたカラー (R,G,B,A)を取り扱うことができる.画像の

ソースには,メモリ内に自動生成した画像データ,レンダリングにより生成された画像,デジカメなどによる

画像などを使用出来る.また,画像上に表示するだけでなく,画像はテクスチャ.マップとして使用し,レン

ダリングされるポリゴンにペーストすることが可能である.

3.1 OpenGLコマンド

ピクセルデータの読み込み

フレーム・バッファからピックセルの方形配列を読み込み,そのデータをメモリに保存する.左下隅が (x,

y)に位置し,その左図が widthと heightで表されるフレームバッファからピクセルデータを読み込み,pixels

が示す配列に保存する.¶ ³void glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height,

GLenum format, GLenum type, GLvoid *pixels);µ ´formatは読み込まれるデータ要素の種類 (RGBA等)を示し,typeは各要素のデータ型式を示す.

フォーマット定数 ピクセルフォーマット

GL COLOR INDEX 単一のカラー指標

GL RGB 赤,緑,青の順序のカラー要素

GL RED 単一の赤のカラー要素

GL GREEN 単一の緑のカラー要素

GL BLUE 単一の青のカラー要素

GL ALPHA 単一のアルファのカラー要素

GL LUMINANCE 単一の輝度要素

GL LUMINANCE ALPHA 輝度要素とアルファのカラー要素

GL STENCIL INDEX 単一のステンシル指標

GL DEPTH COMPONENT 単一のデプス要素

表 1 glReadPixels(),glDrawPixels()のピクセルフォーマット

ピクセルデータの書き込み

メモリに保存されたデータから,glRasterPos*() が指定する現在のラスタ位置にあるフレーム・バッファ

に,ピクセルの方形配列を書き込む. widthと heightのサイズでピクセルデータの方形を描画する.ピクセ

ル方形の左下隅は現在のラスタ位置になる.

Page 10: 平成 20kuni/enshu2008/enshu2008_1027.pdf1 平成20 年度機械情報工学科演習 コンピュータグラフィクス(2) OpenGL+GUI(GLUI) による3DCG の応用 テクスチャマッピング

10 3 画像の取り扱い

形式定数 データ形式

GL UNSIGNED BYTE 符号無し 8ビット整数

GL BYTE 符号付き 8ビット整数

GL UNSIGNED SHORT 符号無し 16ビット整数

GL SHORT 符号付き 16ビット整数

GL UNSIGNED INT 符号無し 32ビット整数

GL INT 符号付き 32ビット整数

GL UNSIGNED BYTE 単精度の浮動小数点

表 2 glReadPixels(),glDrawPixels()のデータ形式

¶ ³void glDrawPixels(GLsizei width, GLsizei height, GLenum format,

GLenum type, GLvoid *pixels);

void glRasterPos{234}{sifd}(TYPE x, TYPE y, TYPE z, TYPE w);

void glRasterPos{234}{sifd}v(TYPE *coords);

formatと typeの意味は,glReadPixels()と同等である.µ ´ピクセルデータのコピー

フレーム・バッファの一部から別の部分にピクセルの方形配列をコピーする glReadPixels() の後に

glDrawPixels()を呼び出したときと同様であるが,メモリには書き込まれない.¶ ³void glCopyPixels(GLint x, GLint y, GLsizei width, GLsizei height,

GLenum buffer);µ ´bufferは GL COLOR, GL STENCIL, GL DEPTHのいずれかのフレームバッファを指定する.

ピクセルデータのパックとアンパック

パックとアンパックは,ピクセルデータがメモリに書き込む,読み込む方法をさす.メモリに保存された画

像は,要素と呼ばれるデータのブロックを 1から 4つ持っている.このデータは,カラー指標や輝度だけで構

成される場合から,各ピクセルに対する赤,緑,青,アルファの要素から構成される場合もある.ピクセル

データの配置方法 fromatは,各ピクセルに保存される要素の数と順番を蹴っている.

画像データは,通常,方形の 2次元,または 3次元配列でメモリに保存されている.多くの場合,配列の部

分方形に対応する部分画像の表示,保存が必要である.可能なピクセル格納モードは,glPixelStore*()で制

御する.

Page 11: 平成 20kuni/enshu2008/enshu2008_1027.pdf1 平成20 年度機械情報工学科演習 コンピュータグラフィクス(2) OpenGL+GUI(GLUI) による3DCG の応用 テクスチャマッピング

3.1 OpenGLコマンド 11

¶ ³void glPixelStore{if}(GLenum pname,TYPE param);µ ´

パラメータ GL UNPACK*は,glDrawPixels(),glTexImage1D(),glTexImage2D(),glTexSubImage1D(),

glTexSubImage2D() がデータをメモリからアンパックする方法を制御する.パラメータ GL PACK*は,

glReadPixels(),glGetTexImage()がデータをメモリにパックする方法を制御する.

パラメタ名 形式 初期値 有効範囲

GL UNPACK SWAP BYTES,

GL PACK SWAP BYTES GLboolean FALSE TRUEFALSE

GL UNPACK LSB BYTES,

GL PACK LSB BYTES GLboolean FALSE TRUEFALSE

GL UNPACK ROW LENGTH,

GL PACK ROW LENGTH GLint 0 任意の非負の整数

GL UNPACK SKIP ROWS,

GL PACK SKIP ROWS GLint 0 任意の非負の整数

GL UNPACK SKIP PIXELS,

GL PACK SKIP PIXELS GLint 0 任意の非負の整数

GL UNPACK ALIGNMENT,

GL PACK ALIGNMENT GLint 4 1,2,3,4

*SKIP_ROWS

*SKIP_PIXELS

*ROW_LENGTH

�æ ��

�� �ª �æ ��

図 6 ピクセル格納モード

ピクセルデータの拡大・縮小・線対称変換¶ ³void glPixelZoom(GLfloat zoom_x,GLfloat zoom_y);µ ´

ピクセルの書き込み時 (glDrawPixels(),glCopyPixels())における拡大,縮小の係数を xと yのサイズで設

定する.初期設定では,zoom xと zoom yは 1.0.どちらも 2.0の場合各ピクセルは 4つのピクセルに描画

Page 12: 平成 20kuni/enshu2008/enshu2008_1027.pdf1 平成20 年度機械情報工学科演習 コンピュータグラフィクス(2) OpenGL+GUI(GLUI) による3DCG の応用 テクスチャマッピング

12 3 画像の取り扱い

される.分数による縮小も可能.係数を負にすると,現在のラスタ位置を中心に線対称変換される.

3.2 簡単な例

次の例は,ウィンドウの左下隅にピクセル方形を描画するプログラムである.

glDrawPixels()の使用:sample-image.c

#include <GL/glut.h>

#include <stdlib.h>

#define checkImageWidth 64

#define checkImageHeight 64

GLubyte checkImage[checkImageHeight][checkImageWidth][3];

static GLdouble zoomFactor = 1.0;

static GLint height;

void makeCheckImage(void)

{

int i, j, c;

for (i = 0; i < checkImageHeight; i++) {

for (j = 0; j < checkImageWidth; j++) {

c = ((((i&0x8)==0)^((j&0x8)==0)))*255;

checkImage[i][j][0] = (GLubyte) c;

checkImage[i][j][1] = (GLubyte) c;

checkImage[i][j][2] = (GLubyte) c;

}

}

}

void init(void)

{

glClearColor (0.0, 0.0, 0.0, 0.0);

glShadeModel(GL_FLAT);

makeCheckImage();

glPixelStorei(GL_UNPACK_ALIGNMENT, 1);

}

Page 13: 平成 20kuni/enshu2008/enshu2008_1027.pdf1 平成20 年度機械情報工学科演習 コンピュータグラフィクス(2) OpenGL+GUI(GLUI) による3DCG の応用 テクスチャマッピング

3.3 画像の読み込み 13

void display(void)

{

glClear(GL_COLOR_BUFFER_BIT);

glRasterPos2i(0, 0);

glDrawPixels(checkImageWidth, checkImageHeight, GL_RGB,

GL_UNSIGNED_BYTE, checkImage);

glFlush();

}

3.3 画像の読み込み

画像をデータとして読み込む関数は標準では用意されていない.そのため,例えば Independent JPEG

Group’s softwareの JPEGライブラリなどを使用する. Linuxシステムにはインストールされている場合が

多い.(http://www.ijg.org/)

JPEGを表示するサンプルプログラム

JPEGファイルから OpenGL用のピクセルデータに格納

viewjpeg.c: OpenGLによる画像表示プログラム

readjpeg.h, readjpeg.c: JPEG画像読み込み用プログラム.

testimg.jpg: テスト画像

JPEGライブラリを使用するMakefileの例.

TARGET = viewjpeg

OBJS = viewjpeg.o readjpeg.o

CC = gcc

CFLAGS = -g -Wall -O2

LIBS = -lglut -lGLU -lGL -ljpeg

TARGET:$(OBJS)

$(CC) -o $(TARGET) $(OBJS) $(LIBS)

.c.o:

$(CC) $(FLAGS) -c $<

clean:

rm -f *.o *~ $(TARGET)

Page 14: 平成 20kuni/enshu2008/enshu2008_1027.pdf1 平成20 年度機械情報工学科演習 コンピュータグラフィクス(2) OpenGL+GUI(GLUI) による3DCG の応用 テクスチャマッピング

14 4 テクスチャ・マッピング

4 テクスチャ・マッピング

物体のディテールを表現する一つの方法はポリゴンにより詳細なモデルを構築することであるが,これには

膨大な手間を必要とし,ポリゴン数が非常に多くなるため表示のための計算負荷が増大する.これに代わる方

法として,物体表面に絵を張りつけることでディテールを表現するテクスチャマッピングの手法が一般的に利

用されている.OpenGLではテクスチャマッピングの機能がサポートされ,これをを比較的容易に行うこと

ができる.なお,曲面形状にテクスチャをマップする場合には,マッピングによって生じるテクスチャの歪み

やその効果に気をつける必要がある.

P r i m i t i v e M o d e l

T e x t u r e

s u r f a c e o f b u i l d i n gs u r f a c e o f w a l lt r e e

S c e n e

図 7 テクスチャ・マッピング技術

4.1 テクスチャマッピングとは

テクスチャマッピングは 3次元の平面に画像を貼り込む技術で,建築物や植物など多くのモデルを自然な表

現に仕上げるにはこの手法がよく利用される.テクスチャマッピングをするには,画像を配列に読み込み,そ

の画像の位置と面の頂点を対応づける.画像と平面は同一形状である必要はない.

テクスチャマッピングは画像を物体の平面に対応づける.マッピングするときは頂点に画像の位置を対応づ

ける.画像の位置は画像の画素数ではなく,画像全体を 0.0...1.0の正規化された座標系で位置を指定する.対

応付けには,頂点座標を指定する前に,対応する画像の位置を指定する.¶ ³void glTexCoord{1,2,3,4}{s,i,d,f}(TYPE coords);

void glTexCoord{1,2,3,4}{s,i,d,f}v(TYPE *coords);µ ´4.2 テクスチャ・オブジェクト

OpenGLでは,テクスチャの取り扱いにおいて,テクスチャ・オブジェクトという機能を利用する.テク

スチャ・オブジェクトはテクスチャ・データを保存し,それが容易に使用できるようにする.多数のテクス

チャを制御し,以前にテクスチャ・リソースにロードされているテクスチャに戻ることが可能である.いちい

ち,画像からロードしなおすより,既存のテクスチャオブジェクトをバインド (再利用)する方がほとんどの

場合で高速である.テクスチャ・オブジェクトを使用することでテクスチャの適用がもっとも高速になり,パ

Page 15: 平成 20kuni/enshu2008/enshu2008_1027.pdf1 平成20 年度機械情報工学科演習 コンピュータグラフィクス(2) OpenGL+GUI(GLUI) による3DCG の応用 テクスチャマッピング

4.3 簡単な例 15

図 8 頂点に画像の座標を対応づける

フォーマンスも向上する.

1. テクスチャオブジェクトを作成し,それにテクスチャを指定する

2. テクスチャを各ピクセルに適用する方法を指示する

3. テクスチャマッピングを有効化する

4. テクスチャ座標と幾何学座標の双方を与えて,シーンを描画する

OpenGLでは,テクスチャにそれぞれ番号をつけて,テクスチャを管理する.多数のテクスチャを制御し,

以前にテクスチャとしてロードされているテクスチャに戻ることが可能になる.

4.3 簡単な例

次の例 (sample-checker.c)は,テクスチャマッピングのサンプルプログラムである. glTexImage2D()の

使用している.

#include <GL/glut.h>

#include <stdlib.h>

/* Create checkerboard texture */

#define checkImageWidth 64

#define checkImageHeight 64

GLubyte checkImage[checkImageWidth][checkImageHeight][3];

void makeCheckImage(void)

{

int i, j, c;

for (i = 0; i < checkImageWidth; i++) {

for (j = 0; j < checkImageHeight; j++) {

c = ((((i&0x8)==0)^((j&0x8)==0)))*255;

Page 16: 平成 20kuni/enshu2008/enshu2008_1027.pdf1 平成20 年度機械情報工学科演習 コンピュータグラフィクス(2) OpenGL+GUI(GLUI) による3DCG の応用 テクスチャマッピング

16 4 テクスチャ・マッピング

checkImage[i][j][0] = (GLubyte) c;

checkImage[i][j][1] = (GLubyte) c;

checkImage[i][j][2] = (GLubyte) c;

}

}

}

void myinit(void)

{

glClearColor (0.0, 0.0, 0.0, 0.0);

glEnable(GL_DEPTH_TEST);

glDepthFunc(GL_LESS);

makeCheckImage();

glPixelStorei(GL_UNPACK_ALIGNMENT, 1);

glTexImage2D(GL_TEXTURE_2D, 0, 3, checkImageWidth,

checkImageHeight, 0, GL_RGB, GL_UNSIGNED_BYTE,

&checkImage[0][0][0]);

glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);

glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);

glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);

glEnable(GL_TEXTURE_2D);

glShadeModel(GL_FLAT);

}

void display(void)

{

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glBegin(GL_QUADS);

glTexCoord2f(0.0, 0.0); glVertex3f(-2.0, -1.0, 0.0);

glTexCoord2f(0.0, 1.0); glVertex3f(-2.0, 1.0, 0.0);

glTexCoord2f(1.0, 1.0); glVertex3f(0.0, 1.0, 0.0);

glTexCoord2f(1.0, 0.0); glVertex3f(0.0, -1.0, 0.0);

Page 17: 平成 20kuni/enshu2008/enshu2008_1027.pdf1 平成20 年度機械情報工学科演習 コンピュータグラフィクス(2) OpenGL+GUI(GLUI) による3DCG の応用 テクスチャマッピング

4.3 簡単な例 17

glTexCoord2f(0.0, 0.0); glVertex3f(1.0, -1.0, 0.0);

glTexCoord2f(0.0, 1.0); glVertex3f(1.0, 1.0, 0.0);

glTexCoord2f(1.0, 1.0); glVertex3f(2.41421, 1.0, -1.41421);

glTexCoord2f(1.0, 0.0); glVertex3f(2.41421, -1.0, -1.41421);

glEnd();

glutSwapBuffers();

}

void myReshape(int w, int h)

{

glViewport(0, 0, w, h);

glMatrixMode(GL_PROJECTION);

glLoadIdentity();

gluPerspective(60.0, 1.0*(GLfloat)w/(GLfloat)h, 1.0, 30.0);

glMatrixMode(GL_MODELVIEW);

glLoadIdentity();

glTranslatef(0.0, 0.0, -3.6);

}

int

main(int argc, char** argv)

{

glutInit(&argc, argv);

glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);

glutCreateWindow("checker");

myinit();

glutReshapeFunc (myReshape);

glutDisplayFunc(display);

glutMainLoop();

return 0; /* ANSI C requires main to return int. */

}

Page 18: 平成 20kuni/enshu2008/enshu2008_1027.pdf1 平成20 年度機械情報工学科演習 コンピュータグラフィクス(2) OpenGL+GUI(GLUI) による3DCG の応用 テクスチャマッピング

18 4 テクスチャ・マッピング

テクスチャの準備

テクスチャの準備は initTexture 関数の中でおこなわれている.テクスチャバッファの2次元配列には,

GLubyte型 (unsigned char)でWIDTHx HEIGHTx 4個となっている.1画素に RGBAの 4バイトを

割り当てている.テクスチャのサイズは縦横とも 2の累乗になっていなければならず,ここでは 64x 64に

なっている.

initTexture関数の内部では,配列にチェック模様を格納していく. 白いチェック模様を描くために,配列

番号の下位1ビットで白黒を判定している.つまり2で割り切れる場合は1,そうでなければ0をcに代入す

る.最終的に配列には0か255の値が代入される.

テクスチャの格納

配列をテクスチャバッファに読みこむ.テクスチャの格納もプログラム初期化時に init 関数にて実行さ

れる.

glPixelStorei()は,テクスチャバッファに格納される際の配列の並びを指定する.

image[ ] という名前のついた配列は並びが連続している,という指定をして,テクスチャバッファに格納

する.

glTexParameteri, glTexParameterfはテクスチャバッファを利用する際の設定をおこない,テクスチャの

反復やクランプ,拡大縮小時の描画に関する制御が可能である.

glTexImage2Dは,配列の内容をテクスチャバッファに格納する実質的なコマンドである.このコマンドで

は以下の引数を持つ.¶ ³void glTexImage2D(GLenum target, GLint level, GLint component,

GLsizei width, GLsizei height, GLint border,

GLenum format, GLenum type, const GLvoid *pixels)µ ´頻繁に使うパラメータは width,height,pixel.width,height はテクスチャバッファのサイズであり,それ

ぞれ 2の累乗であることが必要である.pixelにはテクスチャが格納されている配列へのポインタ (ここでは

image)を指定する.

テクスチャの貼りつけ

テクスチャの切り取り,貼り付け指定は,物体の描画時におこなわれる.ここでは display() 関数で行わ

れる.

重要なのは,テクスチャマッピングを有効にするために,glEnable(GL TEXTURE 2D)をコールすること

である.glDisable(GL TEXTURE 2D)を呼ぶとテクスチャマッピングを無効になる.この切り替えを上手

に行わないと,表示されるポリゴンすべてにテクスチャマッピングが適用される恐れがある.

Page 19: 平成 20kuni/enshu2008/enshu2008_1027.pdf1 平成20 年度機械情報工学科演習 コンピュータグラフィクス(2) OpenGL+GUI(GLUI) による3DCG の応用 テクスチャマッピング

4.4 よく使う OpenGLの関数 19

4.4 よく使う OpenGLの関数

テクスチャオブジェクトの名称設定¶ ³void glGenTextures(GLsizei n, GLuint *textureNames);µ ´

glGenTextures()は,その番号を取得する関数.nには,取得したい数を入れ,textureNamesには,配列

を返す.この番号をテクスチャ用番号として使用する.

テクスチャオブジェクトの作成と使用¶ ³void glBindTexture(GLenum target, GLuint textureName);µ ´

使うテクスチャを選択する.targetは,GL TEXTURE 1Dもしくは GL TEXTURE 2D.textureName

には,使おうとするテクスチャの番号を渡す.

テクスチャの指定¶ ³void glTexImage2D(GLenum target, GLint level, GLint format,

GLsizei width, GLsizei height, GLint border,

GLenum format, GLenum type, const GLvoid *pixels);µ ´2次元テクスチャを定義する. targetには,GL TEXTURE 2Dを入れる.ミップマップを作るときなど

は,GL PROXY TEXTURE 2Dを入れることもある.

levelは通常は 0を指定.自分でミップマップを作る場合,1以上の値を入れる.

formatは読み込まれるデータ要素の種類 (RGBA等).画像と同様であり,GL RGBか GL RGBAを指定

する場合が多い.

widthと heightは,テクスチャマップの幅と高さ.OpenGLでは,テクスチャの大きさは,2の累乗であ

る必要がある.すなわち,1, 2,4,8,16,32,64,128,256・・・.規格上は最低でも 64x64の大きさの

テクスチャがサポートされ,実際には,1024x1024ぐらいはサポートされる.

borderは,テクスチャに枠をつけるなら1を指定する.普通は 0.

formatは,pixelsに渡すデータの形式.通常は,RGB形式で記録されている場合,GL RGBを指定.も

し,PNGなどのフォーマットで透明度設定もあれば,GL RGBAを指定する.

typeには,pixelsに渡すデータの型を指定.通常は各色8ビットなので,GL UNSIGNED BYTEを指定

する.

Page 20: 平成 20kuni/enshu2008/enshu2008_1027.pdf1 平成20 年度機械情報工学科演習 コンピュータグラフィクス(2) OpenGL+GUI(GLUI) による3DCG の応用 テクスチャマッピング

20 4 テクスチャ・マッピング

◇ 課題 2 ◇¶ ³1. sampel-checker.c、sample-texbind.cをダウンロードし,それぞれ実行せよ.テクスチャの

取り込みパラメータや貼り付けパラメータを各自で変更し,指定方法が表示にどう影響する

か確認せよ.

2. JPEG読み込みプログラム viewjpeg.c, readjpeg.cなどをダウンロードし,実行せよ.さら

に,EyeToyを持ってきている人は,EyeToyから画像をキャプチャし,表示せよ.EyeToy

からのキャプチャのやり方の一つとして,「アプリケーション」→「マルチメディア」→

「XawTV」を起動し,「j」ボタンでキャプチャが可能である.EyeToyがない場合は,異なる

画像を表示せよ.

3. sample-image.cを実行し,動作確認せよ.そして,生成する画像イメージの代わりに JPEG

イメージを使用し,同様に拡大縮小を可能にせよ.

4. 一枚のポリゴンではなく,いろいろなオブジェクトについても表示してみよ.glut-

SolidTeapotが実はテクスチャマッピングに対応している.

5. 数枚以上のテクスチャを読み込み,切り替えて表示することにより,パラパラ漫画のように

見えるようにせよ.連続写真は,EyeToy を使って,うまくキャプチャすると良い.(オプ

ション)

µ ´

Page 21: 平成 20kuni/enshu2008/enshu2008_1027.pdf1 平成20 年度機械情報工学科演習 コンピュータグラフィクス(2) OpenGL+GUI(GLUI) による3DCG の応用 テクスチャマッピング

4.4 よく使う OpenGLの関数 21

◇ 課題 3 ◇¶ ³この課題は,本日学習した GLUI とテクスチャマッピングの両方が含まれている.まず,so-

lar system ex.tar.gzをダウンロードして解凍せよ.

1. plant view以下の main.cppの課題となっている部分を修正し実行可能にせよ.

2. orbit view以下の main.cppの課題と成っている部分を修正し実行可能にせよ.

(a)時間と共に,惑星が公転・自転をする.Day rateを変更することにより,惑星の運行の

速度が変更するようにせよ.

(b)また,下図に示す様に惑星の大きさの変更や,表示モードを変更可能にせよ.

µ ´

図 9 課題 3.1 実行時の画面 図 10 課題 3.1 実行時の画面 図 11 課題 3.1 実行時の画面

図 12 課題 3.2 実行時の画面

Page 22: 平成 20kuni/enshu2008/enshu2008_1027.pdf1 平成20 年度機械情報工学科演習 コンピュータグラフィクス(2) OpenGL+GUI(GLUI) による3DCG の応用 テクスチャマッピング

22 4 テクスチャ・マッピング

図 13 課題 3.2 実行時の画面 (ワイヤーフレーム)

図 14 課題 3.2 実行時の画面 (テクスチャ無し)

図 15 課題 3.2 実行時の画面 (軌道無し)