CKER によって翻訳された NeHe の VC OPENGL フレームワークを Delphi バージョンに変換します。
Delphi を使用して OPENGL を学習する兄弟たちに役立つことを願っています。
理由はわかりませんが、私の Delphi 環境では直接実行できませんが、他のマシンでは問題ないようです。
私のマシンでは、EXE ファイルのコンパイルと実行のみが可能です。
このような優れたフレームワークを提供してくれた NeHe に感謝します。また、VC 情報を翻訳してくれた CKER に感謝します。
プログラムプロジェクト1;
用途
オープングル、
窓、
メッセージ;
定数
WND_TITLE = 'OPenGl 基本フレームワーク';
ヴァール
//=============================================== ===========================
// 各 OpenGL はシェーディング コンテキスト テーブルに接続されます。シェーディング コンテキストは、すべての OpenGL 呼び出しを
// デバイス コンテキスト (デバイス記述テーブル) を受け取り、OpenGL シェーディング記述テーブルを hRC として定義し、プログラムが
// ウィンドウを描画するだけで十分な場合は、デバイス記述テーブルも作成する必要があります。Windows デバイス記述テーブルは hDC として定義されます。
// DC はウィンドウを GDI (グラフィックス デバイス インターフェイス) に接続します。そして RC は OpenGL に接続します
// DCへ。
//=============================================== ===========================
h_RC: HGLRC; // レンダリング コンテキスト (シェーディング記述テーブル)。
h_DC: HDC; // デバイスコンテキスト (デバイス記述テーブル)
h_Wnd: HWND;
h_Instance: HINST; // プログラムインスタンス(インスタンス)。
key : Array[0..255] Of Boolean // キーボード ルーチンの配列;
{$R *.res}
//=============================================== ==============================
//ウィンドウ サイズが変更されたかどうかに関係なく、OpenGL シーンのサイズをリセットします (フル スクリーン モードが使用されていないと仮定します)。
// ウィンドウのサイズを変更できない場合でも (フルスクリーン モードなど)、少なくとも 1 回は実行されます————————
//プログラムの最初に視点を設定します。 OpenGL シーンのサイズは、それが表示されるウィンドウのサイズに設定されます。
//=============================================== ==============================
Procedure glResizeWnd(Width, Height: Integer) //GL ウィンドウ サイズをリセットして初期化します。
始める
If (Height = 0) then // 高さが 0 になり、0 による除算例外が発生するのを防ぎます。
高さ := 1;
glViewport(0, 0, width, height); // 現在のビューポート (ビューポート) をリセットします。
//以下の行はパースペクティブ画面を設定します。つまり、遠くにあるものは小さく見えるということです。そうすることで現実が生まれる
//登場シーン。ここでの遠近感は、ウィンドウの幅と高さに基づいて 45 度の視野角として計算されます。 0.1f、100.0fは
//シーン内に描画できる深さの開始点と終了点。
//glMatrixMode(GL_PROJECTION) は、次の 2 行のコードが射影行列に影響を与えることを指定します。
// 射影行列は、シーンに遠近感を追加する役割を果たします。
//glLoadIdentity() はリセットに似ています。選択したマトリックスの状態を元の状態に戻します。
// glLoadIdentity() を呼び出した後、シーンのパースペクティブを設定します。
glMatrixMode(GL_PROJECTION); //射影行列を選択します
glLoadIdentity(); // 射影行列をリセットします。
gluPerspective(45.0, width / height, 0.1, 100.0); // ウィンドウの出現比率を計算します。
//glMatrixMode(GL_MODELVIEW) は、新しい変換がモデルビュー行列 (モデル観測行列) に影響を与えることを指定します。
//オブジェクト情報はモデル観測行列に保存されます。
glMatrixMode(GL_MODELVIEW); //モデル観測行列を選択
glLoadIdentity(); //モデル観測行列をリセット
//これらの用語の意味がまだ理解できなくても、心配する必要はありません。
//素晴らしい視点のシーンを取得したい場合は、これを行う必要があることを知っておいてください。
終わり;
//=============================================== ==============================
// OpenGL に関するすべての設定を行います。画面をクリアする色を設定し、深度キャッシュをオンにし、
// スムースシェーディング(影のスムージング)などを有効にします。このルーチンは、OpenGL ウィンドウが作成されるまで呼び出されません。
// この処理には戻り値があります。ただし、ここでの初期化はそれほど複雑ではないため、戻り値についてはまだ心配する必要はありません。
//=============================================== ==============================
プロシージャ glInit();
始める
//画面をクリアする際の色を設定します。色の仕組みがわからない場合は、ここで簡単に説明します。
//色の値の範囲は0.0fから1.0fです。 0.0f は最も暗い状況を表し、1.0f は最も明るい状況を表します。
//glClearColor の後の最初のパラメータは赤の強度 (赤コンポーネント)、2 番目は緑、3 番目は青です。
//最大値も 1.0f で、これは特定の色コンポーネントの最も明るいケースを表します。最後のパラメータはアルファ値です。
//画面をクリアするために使用する場合、4 番目の数字は気にしません。ここで 0.0f とします。
//三原色(赤、緑、青)を混ぜると、さまざまな色が得られます
//したがって、glClearColor(0.0f,0.0f,1.0f,0.0f)、青を使用して画面をクリアします。
// glClearColor(0.5f,0.0f,0.0f,0.0f) を使用すると、画面をクリアするために中程度の赤が使用されます。
//最も明るい (1.0f) でもなく、最も暗い (0.0f) でもありません。背景を白にするには、すべての色を最も明るい色 (1.0f) に設定する必要があります。
//黒の背景が必要な場合は、すべての色を最も暗い色 (0.0f) に設定します。
glClearColor(0.0, 0.0, 0.0, 0.0); // 黒の背景
//シャドウ スムージングは、ポリゴンを通して色を細かくブレンドし、外光を滑らかにします。
glShadeModel(GL_SMOOTH); // 影のスムージングを有効にする
//次にしなければならないことは、深度バッファーについてです。深度バッファーを画面の背後のレイヤーとして考えてください。
// 深度バッファは、オブジェクトが画面に入る深さを継続的に追跡します。このプログラムは実際には深度キャッシュを使用しません。
//しかし、画面上に 3D シーンを表示するほとんどすべての OpenGL プログラムは深度バッファを使用します。その順序によって、どのオブジェクトが最初に描画されるかが決まります。
//この方法では、円の後ろに四角形を円上に描画する必要はありません。深度バッファは OpenGL の非常に重要な部分です。
glClearDepth(1.0); //深度バッファを設定します。
glEnable(GL_DEPTH_TEST); // 深度テストを有効にする
glDepthFunc(GL_LESS); // 完了した深度テストのタイプ
//次に、可能な限り最高の遠近補正が必要であることを OpenGL に伝えます。
//これはパフォーマンスにわずかに影響します。しかし、視点が少し良くなります。
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // 実に細かい遠近補正
終わり;
//=============================================== ==============================
//すべての描画コード。画面に表示したいものはすべてこのコードに表示されます。
//将来のすべてのプログラムはここに新しいコードを追加します。
//=============================================== ==============================
プロシージャ glDraw();
始める
glClear(GL_COLOR_BUFFER_BIT Or GL_DEPTH_BUFFER_BIT); // 画面と深度バッファをクリアします。
glLoadIdentity(); //現在のモデル観測行列をリセットします。
終わり;
Function WndProc(hWnd: HWND; // ウィンドウのハンドル
Msg: UINT; // ウィンドウメッセージ
wParam: WPARAM; // 追加のメッセージ内容
lParam: LPARAM // 追加のメッセージ内容
): LRESULT;
始める
結果 := 0;
Case (Msg) Of // Windows メッセージを確認する
WM_ACTIVATE: // モニターウィンドウのアクティブ化メッセージ
始める
終わり;
WM_CREATE: // 作成
始める
終わり;
WM_CLOSE: // 閉じる
始める
PostQuitMessage(0); //終了メッセージを送信する
結果 := 0
終わり;
WM_KEYDOWN: // キーが押されました
始める
key[wParam] := True // はいの場合は TRUE に設定します。
結果 := 0;
終わり;
WM_KEYUP: // キーを放します
始める
key[wParam] := False // はいの場合は FALSE に設定します。
結果 := 0;
終わり;
WM_SIZE: //OpenGL ウィンドウ サイズを調整する
始める
glResizeWnd(LOWord(lParam), HIWORD(lParam)); //LoWord=幅,HiWord=高さ
結果 := 0;
終わり;
WM_TIMER: //タイマー
始める
終わり;
Else //残りは Windows に処理させます。
Result := DefWindowProc(hWnd, Msg, wParam, lParam); // 未処理のメッセージをすべて DefWindowProc に渡します。
終わり;
終わり;
//=============================================== ==============================
// プログラムが終了する前にのみ呼び出されます。カラーリングコンテキストテーブル、デバイスコンテキストテーブル、ウィンドウハンドルを順番に解放する機能です。
// 多くのエラーチェックを追加しました。プログラムがウィンドウのどの部分も破壊できない場合は、適切なエラー メッセージがポップアップ表示されます。
// メッセージウィンドウ、
//=============================================== ==============================
プロシージャ glKillWnd(フルスクリーン: ブール値);
始める
// KillGLWindow() で最初に行われるのは、全画面モードかどうかを確認することです。
//「はい」の場合は、デスクトップに戻ります。全画面モードを無効にする前にウィンドウを破棄する必要がありました。
//ただし、一部のグラフィックス カードでこれを実行すると、デスクトップがクラッシュする可能性があります。したがって、最初に全画面モードを無効にすることをお勧めします。
//これにより、デスクトップのクラッシュが防止され、Nvidia と 3dfx の両方のグラフィックス カードでうまく動作します。
フルスクリーンの場合 // フルスクリーン モードですか?
始める
// ChangeDisplaySettings(NULL,0) を使用して、元のデスクトップに戻ります。
// 最初のパラメータとして NULL を受け取ります。
// 2 番目のパラメータとして 0 を渡すと、Windows は現在レジストリに保存されている値を使用するようになります。
// (デフォルトの解像度、色深度、リフレッシュ レートなど) 元のデスクトップを効果的に復元します。
// デスクトップに戻った後、マウス ポインタを再度表示する必要があります。
ChangeDisplaySettings(devmode(Nil^), 0); // はいの場合、デスクトップに戻ります。
ShowCursor(True); //マウスを表示します。
終わり;
//カラーリング記述テーブル (hRC) があるかどうか。
h_RC > 0 の場合
//それを解放できるかどうかを確認します (hRC を hDC から分離します)。
If (wglMakeCurrent(h_DC, 0) ではない) then
MessageBox(0, 'DC と RC は解放できません!', 'エラー', MB_OK または
MB_ICONERROR);
// シェーディング記述テーブルは削除できますか?
If (wglDeleteContext(h_RC) ではない) then
始める
MessageBox(0, 'シェーディング コンテキスト テーブルの削除に失敗しました!', 'エラー', MB_OK または
MB_ICONERROR);
h_RC := 0;
終わり;
//デバイスコンテキストテーブルが存在するかどうか、存在する場合は解放を試みます。
((h_DC > 0) かつ (ReleaseDC(h_Wnd, h_DC) = 0)) の場合
始める
MessageBox(0, 'デバイス コンテキストの解放に失敗しました!'、'エラー'、MB_OK または
MB_ICONERROR);
h_DC := 0;
終わり;
// ウィンドウ ハンドルがあるかどうかに関係なく、DestroyWindow(hWnd) を呼び出してウィンドウの破棄を試みます
If ((h_Wnd <> 0) And (Not DestroyWindow(h_Wnd))) then
始める
MessageBox(0, 'フォームを破棄できません!', 'エラー', MB_OK または
MB_ICONERROR);
h_Wnd := 0;
終わり;
// ウィンドウクラスからログアウトします
//これにより、通常はウィンドウを破棄し、他のウィンドウが開いたときに、
//「Windows Class selected」(ウィンドウクラスはすでに登録されています)などのエラーメッセージは表示されません。
If (Not UnRegisterClass('OpenGL', hInstance)) then
始める
MessageBox(0, 'ウィンドウ クラスからログアウトできません!', 'エラー', MB_OK または
MB_ICONERROR);
hインスタンス:= 0;
終わり;
終わり;