{
このレッスンでは、3 つの異なるテクスチャ フィルタリング方法の使用方法を説明します。
キーボードを使用してシーン内のオブジェクトを移動する方法と、OpenGL シーンに簡単な照明を適用する方法を説明します。
このレッスンには多くの内容が含まれています。前のレッスンについて質問がある場合は、最初に戻って復習してください。
背後にあるコードに入る前に、基本をよく理解することが重要です。
最初のレッスンのコードを引き続き変更します。
以前と違うのは、大きな変更があった場合は必ずコード全体を書き出すことです。
まず、SysUtils ユニットと Glaux ユニットを追加する必要があります。
}
用途
システムユーティリティ、
オープングル、
窓、
メッセージ、
Glaux 内 '../../GLAUX/Glaux.pas';
//次の行は新しい変数を追加します。
// 3 つのブール変数を追加します。
// ライト変数はライトがオンになっているかどうかを追跡します。
//変数 lp と fp は、「L」キーと「F」キーが押されたかどうかを保存するために使用されます。
//これらの変数の重要性については後で説明します。とりあえず、それは脇に置いておいてください。
light : Boolean // 光源のオン/オフ。
lp : Boolean // L キーが押されましたか?
fp : Boolean; // F キーが押されましたか?
//次に、X 軸と Y 軸を中心とした回転角度のステップ サイズを制御する 5 つの変数を設定します。
//そして、X 軸と Y 軸の周りの回転速度。
//さらに、画面の深さまでの距離を制御するために z 変数が作成されます。
xrot : GLfloat // X 回転;
yrot : GLfloat // Y 回転;
xspeed : GLfloat // X 回転速度
yspeed : GLfloat; // Y 回転速度
z : GLfloat = -5.0 f; // 画面奥までの距離
//次に、光源の作成に使用する配列を設定します。
// 2 つの異なるライトを使用します。
//最初のものは環境光と呼ばれます。環境光はあらゆる方向から入ります。
//シーン内のすべてのオブジェクトは環境光によって照らされます。
// 2 番目のタイプの光源は拡散光と呼ばれます。
//拡散光は特定の光源によって生成され、シーン内のオブジェクトの表面に反射を作成します。
//拡散光で直接照らされたオブジェクトの表面は非常に明るくなり、
//かろうじて照らされている領域は暗く見えます。
//これにより、作成した木箱の端に非常に優れたシャドウ効果が生成されます。
//光源を作成するプロセスは、色の作成とまったく同じです。
//最初の 3 つのパラメータは RGB 3 色コンポーネントで、最後のパラメータはアルファ チャネル パラメータです。
//したがって、次のコードでは、半分の明るさ (0.5f) の白い周囲光が得られます。
//周囲光がない場合、拡散光が当たらない領域は非常に暗くなります。
LightAmbient: Array[0..3] Of GLfloat = (0.5, 0.5, 0.5, 1.0); //環境光パラメータ (新規)
//コードの次の行では、最も明るい拡散光を生成します。
//すべてのパラメータ値は最大値の 1.0f となります。
//木箱の前面に映えて見栄えも良くなります。
LightDiffuse: Array[0..3] Of GLfloat = (1.0, 1.0, 1.0, 1.0); // 拡散光パラメータ (新規)
//最後に光源の位置を保存します。
//最初の 3 つのパラメータは glTranslate と同じです。
//XYZ軸上の変位はそれぞれ。
//光を木箱の正面に直接当てたいので、XY 軸の変位は両方とも 0.0 です。
// 3 番目の値は Z 軸上の変位です。
//光が常に木箱の前にあるようにするために、
//そこで、光源を画面から観察者 (つまりあなた) に向かって移動させます。
//通常、画面、つまりモニターのスクリーンガラスの位置を Z 軸の 0.0 点と呼びます。
//最終的に Z 軸の変位は 2.0 に設定されます。
// 光源が見える場合、光源はモニターの前に浮かんでいます。
//もちろん、ボックスがモニターのスクリーン ガラスの後ろになければ、ボックスは見えません。
//『翻訳者注: NeHe の忍耐力に感謝します。
//正直に言うと、なぜ彼はこんな単純なことをそんなに意味のないことを言うのですか?
//しかし、もしすべてが明らかだったとしても、あなたはこのようなページをめくって際限なく読み続けますか? 』
//最後のパラメータは 1.0f として扱われます。
//これにより、ここで指定された座標が光源の位置であることが OpenGL に通知されます。詳細については、今後のチュートリアルで説明します。
LightPosition: Array[0..3] Of GLfloat = (0.0, 0.0, 2.0, 1.0); // 光源位置 (new)
//フィルター変数は、表示時に使用されるテクスチャ タイプを追跡します。
//最初のテクスチャ (テクスチャ 0) は、gl_nearest (非スムーズ) フィルタリング メソッドを使用して構築されます。
// 2 番目のテクスチャ (テクスチャ 1) は gl_linear (線形フィルタリング) メソッドを使用します。
//画面に近い画像ほど滑らかに見えます。
// 3 番目のテクスチャ (テクスチャ 2) はミップマップ フィルタリング メソッドを使用します。
//これにより、非常に見栄えの良いテクスチャが作成されます。
//使用方法に応じて、フィルター変数の値はそれぞれ 0、1、または 2 に等しくなります。
//最初のテクスチャから始めましょう。
//texture は 3 つの異なるテクスチャにストレージ スペースを割り当てます。
//それらはそれぞれ、texture[0]、texture[1]、texture[2]にあります。
filter : Gluint; // フィルターの種類
texture : Array[0..2] Of Gluint // 3 つのテクスチャの保存領域;
プロシージャ glGenTextures(n: GLsizei; 変数テクスチャ: stdcall);
opengl32;
プロシージャ glBindTexture(ターゲット: GLenum; テクスチャ: stdcall);
opengl32;
関数 gluBuild2DMipmaps(ターゲット: GLenum; コンポーネント、幅、高さ: GLint;
形式、タイプ: GLenum; データ: ポインタ): 外部 glu32 名。
'gluBuild2DMipmaps';
{
次に、ビットマップをロードし、それを使用して 3 つの異なるテクスチャを作成します。
このレッスンでは、gaux 補助ライブラリを使用してビットマップを読み込みます。
したがって、コンパイル時に gaux ライブラリが含まれているかどうかを確認する必要があります。
Delphi と VC++ の両方に glaux ライブラリが含まれていることは知っていますが、他の言語にはそれが含まれていることが保証されていません。
「翻訳者注: glaux は OpenGL 補助ライブラリです。OpenGL のクロスプラットフォーム特性によれば、
コードはすべてのプラットフォームで共通である必要があります。ただし、補助ライブラリは公式の OpenGL 標準ライブラリではありません。
すべてのプラットフォームで利用できるわけではありません。ただし、これは Win32 プラットフォームで利用できるようです。
あはは、もちろんBCBでも問題ありません。 』 ここでは新しく追加したコードのみ注釈を付けます。
コードの特定の行について質問がある場合は、チュートリアル 6 を参照してください。
このレッスンでは、テクスチャの読み込みと作成について詳しく説明します。
前のコードの後、glResizeWnd () の前に、
次のコードを追加しました。これは、レッスン 6 でビットマップをロードするために使用したコードとほぼ同じです。
}
関数LoadBmp(ファイル名: pchar): PTAUX_RGBImageRec;
ヴァール
BitmapFile : // ファイルハンドル;
始める
If Filename = '' then // ファイル名が指定されていることを確認してください。
result := Nil // 指定されない場合は、NULL を返します。
BitmapFile := FileOpen(Filename, fmOpenWrite); // ファイルを開いてみる
If BitmapFile > 0 then // ファイルは存在しますか?
始める
FileClose(BitmapFile); //ハンドルを閉じる
result := auxDIBImageLoadA(filename); // ビットマップをロードし、ポインタを返します。
終わり
それ以外
result := Nil; // ロードが失敗した場合は NiL を返します。
終わり;
Function LoadTexture: boolean //ビットマップをロードしてテクスチャに変換します。
ヴァール
Status : boolean // ステータスインジケーター
TextureImage : Array[0..1] Of PTAUX_RGBImageRec // テクスチャの保存領域を作成します。
始める
ステータス := false;
ZeroMemory(@TextureImage, sizeof(TextureImage)); // ポインタを NULL に設定します。
TextureImage[0] := LoadBMP('Walls.bmp');
TextureImage[0] <> Nil の場合
始める
ステータス := TRUE // ステータスを TRUE に設定します。
glGenTextures(1, texture[0]); // テクスチャを作成します。
//レッスン 6 では、線形フィルター処理されたテクスチャ マッピングを使用しました。
//これにはマシンのかなりの処理能力が必要ですが、見た目はかなり良好です。
//このレッスンでは、作成する最初のテクスチャは GL_NEAREST メソッドを使用します。
//原則として、このメソッドは実際にはフィルタリングを実行しません。
//処理能力をほとんど消費せず、見栄えも悪くなります。
//唯一の利点は、プロジェクトが高速マシンでも低速マシンでも正常に実行できることです。
// MIN と MAG の両方に GL_NEAREST を使用していることがわかります。
//GL_NEAREST と GL_LINEAR を混在させることができます。
//テクスチャの見栄えは良くなりますが、速度を重視するため、すべて低品質のマップを使用します。
//MIN_FILTER は、画像がテクスチャの元のサイズより小さく描画される場合に使用されます。
//MAG_FILTER は、画像がテクスチャの元のサイズよりも大きく描画される場合に使用されます。
// 最近接フィルター マップを作成する
glBindTexture(GL_TEXTURE_2D, テクスチャ[0]);
// テクスチャを生成する
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[0].sizeX,
TextureImage[0].sizeY、0、GL_RGB、GL_UNSIGNED_BYTE、
テクスチャイメージ[0].data);
//次のテクスチャは、レッスン 6 の線形フィルタリングのものと同じです。唯一の違いは、今回は配置されていることです。
//テクスチャ[1]。これは 2 番目のテクスチャだからです。置かれた場合
//texture[0]、以前に作成された GL_NEAREST テクスチャを上書きします。
glBindTexture(GL_TEXTURE_2D, texture[1]); //ビットマップデータから生成された一般的なテクスチャを使用します。
// テクスチャを生成する
glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[0].sizeX,
TextureImage[0].sizeY、0、GL_RGB、GL_UNSIGNED_BYTE、
テクスチャイメージ[0].data);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); // 線形フィルタリング
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // 線形フィルタリング
//以下はテクスチャを作成する新しい方法です。ミップマッピング!
//『翻訳者注: この単語は中国語に翻訳できませんが、問題ありません。この段落を読むと、その意味が最も重要であることがわかります。 』
//画面上の画像が非常に小さくなると、多くの詳細が失われることに気づくかもしれません。
//さっきまで良さそうだったパターンが醜くなってしまった。 OpenGL にミップマップされたテクスチャを作成するように指示すると、
//OpenGL は、さまざまなサイズの高品質のテクスチャを作成しようとします。ミップマップされたテクスチャを画面に描画すると、
//OpenGL は、描画用に作成した最も見栄えの良い (より詳細な) テクスチャを選択します。
//元の画像を単に拡大縮小するのではなく(詳細が失われます)。
//私はかつて、OpenGL がテクスチャの幅と高さに課す制限 (64、128、256 など) を回避する方法があると述べました。
// 解決策は gluBuild2DMipmaps です。私が調べたところによると、任意のビットマップを使用してテクスチャを作成できます。
//OpenGL は自動的に通常のサイズに拡大縮小します。
//3 番目のテクスチャなので、texture[2] に保存します。このようにして、このレッスンの 3 つのテクスチャすべてが作成されました。
//MipMapped テクスチャを作成
glBindTexture(GL_TEXTURE_2D, テクスチャ[2]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
GL_LINEAR_MIPMAP_NEAREST); // (新規)
//次の行はミップマップされたテクスチャを生成します。
//3 色 (赤、緑、青) を使用して 2D テクスチャを生成します。
//TextureImage[0].sizeX はビットマップ幅です。
//TextureImage[0].sizeY はビットマップの高さです。
//(====何らかの理由で、Delphi のこの関数には高さパラメータがありません。
//でも、ヘルプにはそれが書かれていて、Delphi が何をするのか分からず、落ち込んでいます。
//最後に、以前に自分で gluBuild2DMipmaps を書きましたが、
// glu32.dll に gluBuild2DMipmaps 関数をロードするには =====)
//GL_RGB は、RGB カラーを順番に使用することを意味します。
//GL_UNSIGNED_BYTE はテクスチャ データの単位がバイトであることを意味します。
//TextureImage[0].data は、テクスチャの作成に使用するビットマップを指します。
gluBuild2DMipmaps(GL_TEXTURE_2D, 3, TextureImage[0].sizeX,
TextureImage[0].sizey、GL_RGB、GL_UNSIGNED_BYTE、
TextureImage[0].data); //(新規) }
終わり;
If assign(TextureImage[0]) then // テクスチャが存在するかどうか
If assign(TextureImage[0].data) then // テクスチャ画像が存在するかどうか
TextureImage[0].data := Nil // テクスチャ画像が占有しているメモリを解放します。
TextureImage[0] := Nil // 画像構造を解放します。
result := ステータス // ステータスを返します。
終わり;
//次に、テクスチャをロードして OpenGL 設定を初期化します。
// GLInit 関数の最初の行では、上記のコードを使用してテクスチャをロードします。
//テクスチャを作成した後、glEnable(GL_TEXTURE_2D) を呼び出して 2D テクスチャ マッピングを有効にします。
//シャドウモードはスムースシェーディング(スムーズシェーディング)に設定されます。
//背景色を黒に設定し、深度テストを有効にして、最適化された遠近法の計算を有効にします。
Procedure glInit(); // ここで OpenGL のすべての設定を開始します
始める
If (Not LoadTexture) then // テクスチャ読み込みサブルーチンを呼び出す
exit; // ロードに失敗した場合は終了します。
glEnable(GL_TEXTURE_2D); // テクスチャマッピングを有効にする
glShadeModel(GL_SMOOTH); // 影のスムージングを有効にする
glClearColor(0.0, 0.0, 0.0, 0.0); // 黒の背景
glClearDepth(1.0); //深度バッファを設定します。
glEnable(GL_DEPTH_TEST); // 深度テストを有効にする
glDepthFunc(GL_LESS); // 完了した深度テストのタイプ
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); //高度に最適化された透視投影計算
// 次に、光源の設定を開始します。下の次の行は、放出される周囲光の量を設定します。
//光源 light1 が発光を開始します。
//このレッスンの開始時に、環境光の量を LightAmbient 配列に保存します。
// 次に、この配列 (半分の明るさの周囲光) を使用します。
glLightfv(GL_LIGHT1, GL_AMBIENT, @LightAmbient[0]); // 環境光を設定します。
//次に拡散光の量を設定します。これは LightDiffuse 配列 (最大輝度の白色光) に格納されます。
glLightfv(GL_LIGHT1, GL_DIFFUSE, @LightDiffuse[0]); // 拡散光を設定します。
//次に光源の位置を設定します。
//位置はLightPosition配列に格納されます
//(木箱の正面中央に正確に位置し、X-0.0、Y-0.0、Z 方向に観察者に向かって 2 単位移動 <画面の外側>)。
glLightfv(GL_LIGHT1, GL_POSITION, @LightPosition); // 光源の位置
//最後に、1 番目の光源を有効にします。 GL_LIGHTING はまだ有効にしていませんが、
//つまり、光が見えないのです。
//覚えておいてください: 光源を設定、配置、または有効にしただけでは機能しません。
//GL_LIGHTING を有効にしない限り。
glEnable(GL_LIGHT1); // 光源 1 番を有効にする
終わり;
//次のコードは、テクスチャ付き立方体を描画します。新しいコードに注釈を付けるだけです。
// アノテーションのないコードについて質問がある場合は、レッスン 6 に戻ってください。
Procedure glDraw(); // すべての描画はここから始まります
始める
glClear(GL_COLOR_BUFFER_BIT Or GL_DEPTH_BUFFER_BIT); // 画面と深度バッファをクリアします。
glLoadIdentity(); //現在のモデル観測行列をリセットします。
//次の 3 行のコードは、テクスチャ キューブを配置して回転します。
//glTranslatef(0.0,0.0,z) は、立方体の Z 単位を Z 軸に沿って移動します。
//glRotatef(xrot,1.0f,0.0f,0.0f) は、立方体を X 軸 xrot を中心に回転させます。
//glRotatef(yrot,0.0f,1.0f,0.0f) は立方体 yrot を Y 軸を中心に回転させます。
glTranslatef(0.0, 0.0, z); // 画面内外に z 単位移動します。
glRotatef(xrot, 1.0, 0.0, 0.0); // X 軸を中心に回転します。
glRotatef(yrot, 0.0, 1.0, 0.0); // Y 軸を中心に回転します。
//次の行は、レッスン 6 で行ったことと似ています。
// 違いは、今回バインドするテクスチャが texture[filter] であることです。
//前のレッスンの texture[0] の代わりに。
//F キーを押すたびに、フィルターの値が増加します。
//この値が 2 より大きい場合、変数フィルターは 0 にリセットされます。
//プログラムが初期化されると、変数フィルターの値も 0 に設定されます。
//変数フィルターを使用して、3 つのテクスチャのいずれかを選択できます。
glBindTexture(GL_TEXTURE_2D, texture[filter]) //フィルターで決定されたテクスチャを選択します。
glBegin(GL_QUADS); // 四角形の描画を開始します
//glNormal3f はこのレッスンの初心者です。ノーマルとは普通という意味です。
//いわゆる法線とは、面(ポリゴン)上の点を通り、この面(ポリゴン)に垂直な直線を指します。
//光源を使用する場合は法線を指定する必要があります。法線は OpenGL に多角形の方向を伝え、多角形の表側と裏側を示します。
//法線を指定しないと、照明されてはいけない面が照明されたり、ポリゴンの裏側も照明されたりするという奇妙なことが起こる可能性があります。
//ちなみに、法線はポリゴンの外側を指す必要があります。ボックスの前面を見ると、法線が正の Z 軸と同じ方向を向いていることがわかります。
//これは、法線が観察者、つまりあなた自身の方向を向いていることを意味します。これはまさに私たちが望んでいることです。
//木箱の裏側は、希望どおり、法線が見る側から反対側を向いています。
//立方体が X 軸または Y 軸に沿って 180 度回転した場合、前面の法線は依然として観察者に面しており、背面の法線は依然として観察者から離れた方向を向いています。
//言い換えれば、それがどの表面であっても、それが観察者に面している限り、この表面の法線は観察者を指します。
//光源は観察者のすぐ隣にあるため、法線が観察者に面しているときはいつでも、このサーフェスが照らされます。
//法線が光源に近づくほど、明るく表示されます。
//立方体の内側に観測点を置くと、法線の内側に暗闇が生じます。
//法線が外側を向いているため。立方体の内部に光源がなければ、当然真っ暗になります。
// フロント
glNormal3f(0.0, 0.0, 1.0); // 法線はオブザーバーを指します
glTexCoord2f(0.0, 0.0);
glVertex3f(-1.0, -1.0, 1.0); // クワッドのテクスチャと左下
glTexCoord2f(1.0, 0.0);
glVertex3f(1.0, -1.0, 1.0); // クワッドのテクスチャと右下
glTexCoord2f(1.0, 1.0);
glVertex3f(1.0, 1.0, 1.0); //クワッドのテクスチャと右上
glTexCoord2f(0.0, 1.0);
glVertex3f(-1.0, 1.0, 1.0); //クワッドのテクスチャと左上
// 後で
glNormal3f(0.0, 0.0, -1.0); // 通常はビューアから遠ざかる方向を向きます
glTexCoord2f(1.0, 0.0);
glVertex3f(-1.0, -1.0, -1.0); // クワッドのテクスチャと右下
glTexCoord2f(1.0, 1.0);
glVertex3f(-1.0, 1.0, -1.0); //クワッドのテクスチャと右上
glTexCoord2f(0.0, 1.0);
glVertex3f(1.0, 1.0, -1.0); //クワッドのテクスチャと左上
glTexCoord2f(0.0, 0.0);
glVertex3f(1.0, -1.0, -1.0); // クワッドのテクスチャと左下
// 上面
glNormal3f(0.0, 1.0, 0.0); // 通常の上向き
glTexCoord2f(0.0, 1.0);
glVertex3f(-1.0, 1.0, -1.0); //クワッドのテクスチャと左上
glTexCoord2f(0.0, 0.0);
glVertex3f(-1.0, 1.0, 1.0); // クワッドのテクスチャと左下
glTexCoord2f(1.0, 0.0);
glVertex3f(1.0, 1.0, 1.0); // クワッドのテクスチャと右下
glTexCoord2f(1.0, 1.0);
glVertex3f(1.0, 1.0, -1.0); //クワッドのテクスチャと右上
// 底
glNormal3f(0.0, -1.0, 0.0); // 法線は下向き
glTexCoord2f(1.0, 1.0);
glVertex3f(-1.0, -1.0, -1.0); // クワッドのテクスチャと右上
glTexCoord2f(0.0, 1.0);
glVertex3f(1.0, -1.0, -1.0); //クワッドのテクスチャと左上
glTexCoord2f(0.0, 0.0);
glVertex3f(1.0, -1.0, 1.0); // クワッドのテクスチャと左下
glTexCoord2f(1.0, 0.0);
glVertex3f(-1.0, -1.0, 1.0); // クワッドのテクスチャと右下
// 右
glNormal3f(1.0, 0.0, 0.0); // 右に法線
glTexCoord2f(1.0, 0.0);
glVertex3f(1.0, -1.0, -1.0); // クワッドのテクスチャと右下
glTexCoord2f(1.0, 1.0);
glVertex3f(1.0, 1.0, -1.0); //クワッドのテクスチャと右上
glTexCoord2f(0.0, 1.0);
glVertex3f(1.0, 1.0, 1.0); //クワッドのテクスチャと左上
glTexCoord2f(0.0, 0.0);
glVertex3f(1.0, -1.0, 1.0); // クワッドのテクスチャと左下
// 左
glNormal3f(-1.0, 0.0, 0.0); // 左に法線
glTexCoord2f(0.0, 0.0);
glVertex3f(-1.0, -1.0, -1.0); // クワッドのテクスチャと左下
glTexCoord2f(1.0, 0.0);
glVertex3f(-1.0, -1.0, 1.0); // クワッドのテクスチャと右下
glTexCoord2f(1.0, 1.0);
glVertex3f(-1.0, 1.0, 1.0); //クワッドのテクスチャと右上
glTexCoord2f(0.0, 1.0);
glVertex3f(-1.0, 1.0, -1.0); //クワッドのテクスチャと左上
glEnd();
xrot := xrot + xspeed // xrot は xspeed 単位を増加させます。
yrot := Yrot + yspeed // yrot は yspeed 単位を増加させます。
終わり;
// 次に、WinMain() メイン関数に進みます。
//ここに制御コードを追加して、光源のオンとオフを切り替え、木箱を回転させ、フィルタリング方法を切り替え、木箱を近づけたり遠ざけたりします。
// WinMain() 関数の終わり近くに、SwapBuffers(hDC) のコード行が表示されます。
// 次に、この行の後に次のコードを追加します。
//コードは L キーが押されたかどうかをチェックします。
//L キーが押されたが、lp の値が false でない場合は、L キーが離されていないことを意味し、この時点では何も起こりません。
SwapBuffers(h_DC); // スワップバッファ(ダブルバッファ)
If (keys[ord('L')] And Not lp) then
始める
// lp の値が false の場合、
//L キーがまだ押されていない、または放された場合、lp は TRUE に設定されることを意味します。
//これら 2 つの条件を同時にチェックするのは、L キーが押されるのを防ぐためです。
//このコードは繰り返し実行され、フォームが継続的に点滅します。
//lp が true に設定されると、コンピューターは L キーが押されたことを認識します。
//それに応じて光源のオン/オフを切り替えることができます。ブール変数ライトは光源のオン/オフを制御します。
lp := true // lp は TRUE に設定されます。
light := ライトではありません // 光源を TRUE/FALSE に切り替えます。
If Not light then // 光源がない場合
glDisable(GL_LIGHTING) //光源を無効にする
それ以外 // その他
glEnable(GL_LIGHTING); //光源を有効にする
終わり;
If Not Keys[ord('L')] then //L キーは離されましたか?
lp := FALSE // はいの場合、lp を FALSE に設定します。
//次に、「F」キーについても同様のチェックを行います。
//「F」キーが押されていて、「F」キーが押されていない、または一度も押されていない場合、
//変数 fp を true に設定します。これはキーが押されていることを意味します。
//次にフィルター変数に 1 を追加します。フィルター変数が 2 より大きい場合
//(ここで使用する配列はtexture[3]なので、2より大きいテクスチャは存在しません),
//フィルター変数を 0 にリセットします。
If (keys[ord('F')] And Not fp) then // F キーが押されていますか?
始める
fp := TRUE // fp は TRUE に設定されます。
inc(filter); // フィルタの値に 1 を加算します。
If filter > 2 then // それは 2 より大きいですか?
フィルタ := 0; // 0 にリセットされた場合
終わり;
If Not Keys[ord('F')] then //F キーは離されましたか?
fp := FALSE // fp が FALSE に設定されている場合;
//これらの 4 行は、PageUp キーが押されたかどうかをチェックします。その場合は、z 変数の値を減らします。このように、DrawGLScene 関数に含まれる glTranslatef(0.0f,0.0f,z) の呼び出しにより、木箱がビューアからさらに遠ざかります。
Keys[VK_PRIOR] の場合 //PageUp が押されましたか?
z := z - 0.02; // 押すと木箱を画面内側に移動します。
//次の 4 行では、PageDown キーが押されたかどうかを確認し、押されている場合は、z 変数の値を増やします。このように、DrawGLScene 関数に含まれる glTranslatef(0.0f,0.0f,z) 呼び出しは、木箱を観察者に近づけます。
If Keys[VK_NEXT] then // PageDown が押されましたか?
z := z + 0.02; // 押すと、木箱が観察者の方向に移動します。
// 次に、矢印キーを確認します。左右の方向キーを押すと、それに応じて xspeed が増減します。
//上下の方向キーを押すと、それに応じて yspeed が増減します。
//今後のチュートリアルでは、xspeed と yspeed の値を増やすと、立方体の回転速度が速くなることを覚えておいてください。
//特定の方向キーを押し続けると、立方体はその方向に速く回転します。
If Keys[VK_UP] then // 上方向キーが押されましたか?
xspeed := xspeed - 0.01; //はいの場合は、xspeed を下げます。
If Keys[VK_DOWN] then //下方向キーが押されましたか?
xspeed := xspeed + 0.01; //はいの場合、xspeed を増やします。
If Keys[VK_RIGHT] then //右方向キーが押されましたか?
yspeed := yspeed + 0.01; //はいの場合、yspeed を増やします。
If Keys[VK_LEFT] then //左方向キーが押されましたか?
yspeed := yspeed - 0.01; //はいの場合、yspeed を下げます。
If (keys[VK_ESCAPE]) then // ESC キーが押された場合
終了 := True
実行して効果を確認してください