Ubah kerangka kerja VC OPENGL NeHe yang diterjemahkan oleh CKER ke dalam versi Delphi.
Semoga bermanfaat bagi saudara-saudara yang menggunakan Delphi untuk mempelajari OPENGL.
Saya tidak tahu kenapa, tapi ini tidak bisa berjalan langsung di lingkungan Delphi saya, tapi sepertinya baik-baik saja di mesin lain.
Mesin saya hanya dapat mengkompilasi dan menjalankan file EXE.
Terima kasih kepada NeHe yang telah menyediakan kerangka kerja yang baik, dan terima kasih kepada CKER yang telah menerjemahkan informasi VC.
Program Proyek1;
Kegunaan
terbuka,
jendela,
Pesan;
Konstan
WND_TITLE = 'kerangka dasar OPenGl'; //Judul
Var
//------------------------------------------------ ============
// Setiap OpenGL terhubung ke konteks bayangan. Tabel konteks bayangan menghubungkan semua panggilan OpenGL ke
// Menerima Konteks Perangkat (tabel deskripsi perangkat) dan menentukan tabel deskripsi bayangan OpenGL sebagai hRC, sehingga program dapat
// Jika menggambar jendela saja sudah cukup, Anda juga perlu membuat tabel deskripsi perangkat. Tabel deskripsi perangkat Windows didefinisikan sebagai hDC,
// DC menghubungkan jendela ke GDI (Graphics Device Interface). Dan RC menghubungkan OpenGL
// ke DC.
//------------------------------------------------ ============
h_RC: HGLRC; // Rendering Konteks (tabel deskripsi bayangan).
h_DC: HDC; // Konteks Perangkat (tabel deskripsi perangkat)
h_Wnd: HWND; // pegangan jendela
h_Instance: HINST; // Contoh Program (contoh).
kunci : Array[0..255] Dari Boolean; // Array untuk rutinitas keyboard
{$R *.res}
//------------------------------------------------ ===============
//Reset ukuran adegan OpenGL terlepas dari apakah ukuran jendela telah berubah (dengan asumsi mode layar penuh tidak digunakan).
//Bahkan ketika jendela tidak dapat diubah ukurannya (misalnya dalam mode layar penuh), jendela akan tetap berjalan setidaknya sekali————————
//Tetapkan perspektif di awal program. Ukuran adegan OpenGL akan diatur ke ukuran jendela yang menampilkannya.
//------------------------------------------------ ===============
Prosedur glResizeWnd(Lebar, Tinggi: Integer); //Reset dan inisialisasi ukuran jendela GL
Mulai
If (Tinggi = 0) Then // Cegah tingginya menjadi 0 dan menyebabkan pengecualian bagi-dengan-0.
Tinggi := 1;
glViewport(0, 0, Lebar, Tinggi); //Setel ulang area pandang saat ini (Area Pandang)
//Baris berikut mengatur layar perspektif. Artinya benda yang letaknya lebih jauh akan tampak lebih kecil. Melakukan hal itu menciptakan kenyataan
//Adegan penampilan. Perspektif di sini dihitung sebagai sudut pandang 45 derajat berdasarkan lebar dan tinggi jendela. 0,1f, 100,0f adalah
//Titik awal dan titik akhir dari kedalaman yang dapat kita gambar dalam adegan.
//glMatrixMode(GL_PROJECTION) menetapkan bahwa dua baris kode berikutnya akan mempengaruhi matriks proyeksi.
//Matriks proyeksi bertanggung jawab untuk menambahkan perspektif pada pemandangan kita.
//glLoadIdentity() mirip dengan mengatur ulang. Ini mengembalikan keadaan matriks yang dipilih ke keadaan semula.
//Setelah memanggil glLoadIdentity() kita menetapkan perspektif untuk adegan tersebut.
glMatrixMode(GL_PROJECTION); //Pilih matriks proyeksi
glLoadIdentity(); // Reset matriks proyeksi
gluPerspective(45.0, Lebar / Tinggi, 0.1, 100.0); // Hitung proporsi tampilan jendela
//glMatrixMode(GL_MODELVIEW) menetapkan bahwa setiap transformasi baru akan mempengaruhi matriks modelview (matriks observasi model).
//Informasi objek kita disimpan dalam matriks observasi model.
glMatrixMode(GL_MODELVIEW); //Pilih matriks observasi model
glLoadIdentity(); //Setel ulang matriks observasi model
//Jika Anda belum memahami arti istilah-istilah ini, jangan khawatir.
//Ketahuilah bahwa Anda harus melakukan ini jika Anda ingin mendapatkan pemandangan perspektif yang bagus.
Akhir;
//------------------------------------------------ ===============
// Buat semua pengaturan untuk OpenGL. Atur warna untuk membersihkan layar, aktifkan cache kedalaman,
// Aktifkan bayangan halus (penghalusan bayangan), dll. Rutinitas ini tidak dipanggil sampai jendela OpenGL dibuat.
// Proses ini akan memiliki nilai kembalian. Namun inisialisasi di sini tidak terlalu rumit, dan tidak perlu mengkhawatirkan nilai kembaliannya.
//------------------------------------------------ ===============
Prosedur glInit();
Mulai
//Mengatur warna yang digunakan saat membersihkan layar. Jika Anda tidak yakin bagaimana warna bekerja, berikut penjelasan singkatnya.
//Nilai warna berkisar dari 0,0f hingga 1,0f. 0.0f mewakili situasi paling gelap, dan 1.0f adalah situasi paling terang.
//Parameter pertama setelah glClearColor adalah Intensitas Merah (komponen merah), parameter kedua berwarna hijau, dan parameter ketiga berwarna biru.
//Nilai maksimumnya juga 1,0f, yang mewakili huruf paling terang dari komponen warna tertentu. Parameter terakhir adalah nilai Alpha.
//Saat digunakan untuk membersihkan layar, tidak peduli dengan angka keempat. Sekarang biarkan menjadi 0,0f.
//Dengan mencampurkan tiga warna primer (merah, hijau, biru), Anda bisa mendapatkan warna yang berbeda
//Jadi, gunakan glClearColor(0.0f,0.0f,1.0f,0.0f), warna biru Anda untuk membersihkan layar.
//Jika Anda menggunakan glClearColor(0.5f,0.0f,0.0f,0.0f), warna merah sedang akan digunakan untuk membersihkan layar.
//Bukan yang paling terang (1.0f), maupun yang paling gelap (0.0f). Untuk mendapatkan latar belakang putih, semua warna harus diatur ke paling terang (1.0f).
//Jika Anda menginginkan latar belakang hitam, atur semua warna ke yang paling gelap (0,0f).
glClearColor(0.0, 0.0, 0.0, 0.0); // latar belakang hitam
//Penghalusan bayangan memadukan warna dengan halus melalui poligon dan menghaluskan cahaya eksternal.
glShadeModel(GL_SMOOTH); // Aktifkan penghalusan bayangan
//Hal selanjutnya yang harus dilakukan adalah mengenai depth buffer. Bayangkan buffer kedalaman sebagai lapisan di belakang layar.
// Buffer kedalaman terus melacak seberapa dalam objek memasuki layar. Program ini sebenarnya tidak menggunakan depth cache.
//Tetapi hampir semua program OpenGL yang menampilkan adegan 3D di layar menggunakan buffer kedalaman. Urutannya menentukan objek mana yang digambar terlebih dahulu.
//Dengan cara ini kamu tidak menggambar kotak di belakang lingkaran ke dalam lingkaran. Buffer kedalaman adalah bagian yang sangat penting dari OpenGL.
glClearDepth(1.0); //Setel buffer kedalaman
glEnable(GL_DEPTH_TEST); // Aktifkan pengujian kedalaman
glDepthFunc(GL_LESS); // Jenis pengujian kedalaman selesai
//Kemudian beritahu OpenGL bahwa kita menginginkan koreksi perspektif terbaik.
//Ini akan sedikit mempengaruhi kinerja. Namun membuat perspektifnya terlihat sedikit lebih baik.
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Koreksi perspektif yang sangat bagus
Akhir;
//------------------------------------------------ ===============
//Semua kode gambar. Apa pun yang ingin Anda tampilkan di layar akan muncul dalam kode ini.
//Setiap program di masa depan akan menambahkan kode baru di sini.
//------------------------------------------------ ===============
Prosedur glDraw();
Mulai
glClear(GL_COLOR_BUFFER_BIT Atau GL_DEPTH_BUFFER_BIT); // Hapus buffer layar dan kedalaman
glLoadIdentity(); //Reset matriks observasi model saat ini
Akhir;
Fungsi WndProc(hWnd: HWND; // pegangan jendela
Pesan: UINT; // Pesan jendela
wParam: WPARAM; // Konten pesan tambahan
lParam: LPARAM // Isi pesan tambahan
): HASIL;
Mulai
Hasil := 0;
Case (Pesan) Dari // Periksa pesan Windows
WM_ACTIVATE: // Pesan aktivasi jendela monitor
Mulai
Akhir;
WM_CREATE: // Buat
Mulai
Akhir;
WM_CLOSE: // tutup
Mulai
PostQuitMessage(0); //Kirim pesan keluar
Hasil := 0
Akhir;
WM_KEYDOWN: // tombol ditekan
Mulai
kunci[wParam] := Benar; // Jika ya, setel ke TRUE
Hasil := 0;
Akhir;
WM_KEYUP: // Lepaskan kuncinya
Mulai
kunci[wParam] := Salah; // Jika ya, setel ke FALSE
Hasil := 0;
Akhir;
WM_SIZE: //Menyesuaikan ukuran jendela OpenGL
Mulai
glResizeWnd(LOWord(lParam), HIWORD(lParam)); //LoWord=Lebar,HiWord=Tinggi
Hasil := 0;
Akhir;
WM_TIMER: //timer
Mulai
Akhir;
Else //Biarkan Windows menangani sisanya.
Hasil := DefWindowProc(hWnd, Msg, wParam, lParam); // Teruskan semua pesan yang belum diproses ke DefWindowProc.
Akhir;
Akhir;
//------------------------------------------------ ===============
// Hanya dipanggil sebelum program keluar. Fungsinya untuk melepaskan tabel konteks pewarnaan, tabel konteks perangkat, dan pegangan jendela secara berurutan.
// Menambahkan banyak pemeriksaan kesalahan. Jika program tidak dapat menghancurkan bagian mana pun dari jendela, pesan kesalahan yang sesuai akan muncul.
// jendela pesan,
//------------------------------------------------ ===============
Prosedur glKillWnd(Layar Penuh: Boolean);
Mulai
//Hal pertama yang dilakukan di KillGLWindow() adalah memeriksa apakah mode layar penuh.
//Jika ya, beralih kembali ke desktop. Jendela seharusnya dihancurkan sebelum menonaktifkan mode layar penuh,
//Tetapi melakukan ini pada beberapa kartu grafis mungkin membuat desktop crash. Jadi lebih baik nonaktifkan mode layar penuh terlebih dahulu.
//Ini akan mencegah desktop crash dan berfungsi dengan baik pada kartu grafis Nvidia dan 3dfx!
Jika Layar Penuh Lalu // Dalam mode layar penuh?
Mulai
// Gunakan ChangeDisplaySettings(NULL,0) untuk kembali ke desktop asli.
// Ambil NULL sebagai parameter pertama,
// Meneruskan 0 sebagai parameter kedua memaksa Windows untuk menggunakan nilai yang saat ini disimpan di registri
// (resolusi default, kedalaman warna, kecepatan refresh, dll.) untuk memulihkan desktop asli saya secara efektif.
// Setelah beralih kembali ke desktop, penunjuk tetikus harus terlihat kembali.
ChangeDisplaySettings(devmode(Nil^), 0); // Jika ya, beralih kembali ke desktop
Tampilkan Kursor (Benar); //Tampilkan mouse
Akhir;
//Apakah memiliki tabel deskripsi pewarnaan (hRC).
Jika h_RC > 0 Maka
//Lihat apakah kita dapat membebaskannya (pisahkan hRC dari hDC).
Jika (Bukan wglMakeCurrent(h_DC, 0)) Lalu
MessageBox(0, 'DC dan RC tidak dapat dilepaskan!', 'Error', MB_OK Atau
MB_ICONERROR);
// Bisakah tabel deskripsi bayangan dihapus?
Jika (Bukan wglDeleteContext(h_RC)) Lalu
Mulai
MessageBox(0, 'Gagal menghapus tabel konteks bayangan!', 'Kesalahan', MB_OK Atau
MB_ICONERROR);
jam_RC := 0;
Akhir;
//Apakah tabel konteks perangkat ada, dan jika demikian, coba lepaskan.
Jika ((h_DC > 0) Dan (ReleaseDC(h_Wnd, h_DC) = 0)) Maka
Mulai
MessageBox(0, 'Gagal merilis konteks perangkat!', 'Kesalahan', MB_OK Atau
MB_ICONERROR);
h_DC := 0;
Akhir;
//Apakah ada pegangan jendela, panggil DestroyWindow(hWnd) untuk mencoba menghancurkan jendela
Jika ((h_Wnd <> 0) Dan (Tidak DestroyWindow(h_Wnd))) Lalu
Mulai
MessageBox(0, 'Tidak dapat menghancurkan formulir!', 'Kesalahan', MB_OK Atau
MB_ICONERROR);
h_Wnd := 0;
Akhir;
//Keluar dari kelas jendela
//Ini memungkinkan kita untuk menghancurkan jendela secara normal dan kemudian membuka jendela lain,
//Anda tidak akan menerima pesan kesalahan seperti "Kelas Windows sudah terdaftar" (kelas jendela sudah terdaftar).
Jika (Bukan UnRegisterClass('OpenGL', hInstance)) Lalu
Mulai
MessageBox(0, 'Tidak dapat keluar dari kelas jendela!', 'Kesalahan', MB_OK Atau
MB_ICONERROR);
hInstance := 0;
Akhir;
Akhir;