Karena OpenGL.pas versi Delphi sendiri adalah versi 1.0, dan yang sebenarnya digunakan sekarang setidaknya versi 1.1, dan metode simulasi perangkat lunak murni Windows juga versi 1.1, jadi Anda harus mengimpor sendiri beberapa fungsi yang diperlukan. Beberapa unit gratis sumber terbuka juga tersedia, seperti OpenGL12.pas milik Mike Lischke. Tentu saja, menulisnya sendiri dapat membuat desain lebih ringkas, dan Anda tidak perlu menemukan kesalahan dalam kode besar yang terlalu canggih dan lengkap.
Pertama perkenalkan unit yang diperlukan Windows, Pesan, OpenGL
Untuk menambahkan beberapa ekstensi yang diperlukan.
konstanta
//GL_EXT_bgra
GL_BGR_EXT = $80E0;
GL_BGRA_EXT = $80E1;
// offset poligon
GL_POLYGON_OFFSET_UNITS = $2A00;
GL_POLYGON_OFFSET_POINT = $2A01;
GL_POLYGON_OFFSET_LINE = $2A02;
GL_POLYGON_OFFSET_FILL = $8037;
GL_POLYGON_OFFSET_FACTOR = $8038;
Prosedur glBindTexture(target: GLEnum; tekstur: GLuint);
prosedur glDeleteTextures(n: GLsizei; tekstur: PGLuint);
prosedur glGenTextures(n: GLsizei; tekstur: PGLuant);
fungsi glIsTexture(tekstur: GLuint): GLboolean; stdcall eksternal;
prosedur glPolygonOffset(faktor, unit: GLfloat);
// Pernyataan ini digunakan untuk memperbaiki bug di OpenGL.pas
fungsi gluBuild2DMipmaps(target: GLEnum; komponen, lebar, tinggi: GLint; format, atype: GLEnum; Data: Pointer): GLint;
Sekarang antarmuka pada dasarnya telah ditingkatkan ke versi 1.1. Jika ekstensi lain diperlukan, ekstensi tersebut dapat ditambahkan dengan cara yang sama.
Selanjutnya, Anda perlu membuat RC konteks gambar OpenGL, yang mana Anda memerlukan konteks perangkat DC dari jendela GDI. Properti TForm.Handle atau properti Handle lainnya dari TWinControl adalah DC. Anda dapat menggunakan fungsi berikut untuk membuat RC dari DC, dan nilai yang dikembalikan adalah pegangan RC. Anda kemudian dapat menggambar menggunakan OpenGL. Umumnya dapat digunakan dalam acara OnCreate di Formulir. Pilihan fungsi ini berarti buffer kedalaman, buffer template, buffer akumulasi, dan menghasilkan nilai saluran Alpha.
jenis
TRCOptions = kumpulan (roDepth, roStencil, roAccum, roAlpha);
fungsi CreateRC(dc: HDC; pilih: TRCOptions): HGLRC;
var
Deskriptor PF: Deskriptor TPixelFormat;
Format Piksel: Bilangan Bulat;
mulai
FillChar(PFDescriptor, SizeOf(PFDescriptor), 0);
dengan PFDescriptor lakukan
mulai
nUkuran := Ukuran(PFDescriptor);
nVersi := 1;
dwFlags := PFD_SUPPORT_OPENGL atau PFD_DRAW_TO_WINDOW atau PFD_DOUBLEBUFFER;
iPixelType := PFD_TYPE_RGBA;
cColorBits := GetDeviceCaps(DC, BITSPIXEL) * GetDeviceCaps(DC, PESAWAT);
jika roDepth di pilih maka cDepthBits := 24;
jika roStencil di opt maka cStencilBits := 8;
jika roAccum di pilih maka cAccumBits := 64;
iLayerType := PFD_MAIN_PLANE;
akhir;
PixelFormat := PilihPixelFormat(DC, @PFDescriptor);
Tegaskan(Format Piksel <> 0);
Tegaskan(SetPixelFormat(DC, PixelFormat, @PFDescriptor));
Hasil := wglCreateContext(DC);
Tegaskan(Hasil <> 0);
wglMakeCurrent(dc, Hasil);
akhir;
Gambarlah acara OnPaint Formulir. Ingat, setelah gambar selesai, SwapBuffers (dc: HDC) harus digunakan untuk menukar buffer gambar dan buffer tampilan agar gambar dapat ditampilkan. Ingatlah juga untuk memanggil glViewport(0, 0, ClientWidth, ClientHeight); dalam acara OnResize Formulir sehingga RC dan DC dapat disinkronkan.
Hancurkan RC di acara OnDestroy Formulir.
prosedur DestroyRC(rc: HGLRC);
mulai
jika rc = 0 maka Keluar;
wglMakeCurrent(0, 0);
wglDeleteContext(rc);
akhir;
Pada titik ini, kerangka program OpenGL secara kasar telah terbentuk. Namun masih ada masalah yang harus diselesaikan.
Pertama, cegah Windows menghapus latar belakang dan memengaruhi kecepatan. Tambahkan fungsi anggota ke Formulir
pribadi
prosedur WMeraseBkgnd(var Pesan: TWmEraseBkgnd); pesan WM_ERASEBKGND;
prosedur TGLWindow.WMeraseBkgnd(var Pesan: TWmEraseBkgnd);
mulai
Pesan.Hasil := 1;
akhir;
Kedua, agar lebih aman. Tambahkan fungsi anggota berikut.
terlindung
prosedur CreateParams(var Params: TCreateParams);
prosedur TGLWindow.CreateParams(var Params: TCreateParams);
mulai
diwariskan;
dengan Params melakukannya
mulai
Gaya := Gaya atau WS_CLIPCHILDREN atau WS_CLIPSIBLINGS;
WindowClass.Style := CS_VREDRAW atau CS_HREDRAW atau CS_OWNDC;
akhir;
akhir;
Oke, sekarang Anda bisa melupakan hal-hal merepotkan ini dan menulis tampilan 3D Anda yang indah :)
Saya harus mengatakan beberapa kata, jangan membuat beberapa RC dalam satu thread, karena ini akan sangat mempengaruhi kinerja. Beberapa demonstrasi kontrol jendela OpenGL pribadi menempatkan beberapa kontrol pada Formulir, yang sebenarnya bukan ide bagus. Beberapa tampilan harus ditampilkan dengan satu jendela OpenGL. Selain itu, jangan mengakses fungsi OpenGL di seluruh thread.
Selain itu, ketika Windows secara otomatis menginstal driver kartu grafis, Windows tidak akan menginstal akselerasi perangkat keras OpenGL. Anda harus menginstal sendiri driver dari produsen kartu grafis!
Selain itu, fungsi tampilan layar penuh gratis disediakan :)
fungsi Layar Penuh(menang: TWinControl; lebar, tinggi, kedalaman bit: integer): boolean;
var mode tampilan: DEVMODE;
mulai
FillChar(mode tampilan, ukuran(mode tampilan), 0);
dengan mode tampilan lakukan
mulai
Ukuran dm := ukuran(mode tampilan);
dmPelsLebar:= lebar;
dmPelsHeight := tinggi;
dmBitsPerPel := kedalaman bit;
dmFields := DM_BITSPERPEL atau DM_PELSWIDTH atau DM_PELSHEIGHT;
akhir;
jika ChangeDisplaySettings(mode tampilan, CDS_FULLSCREEN) = DISP_CHANGE_SUCCESSFUL
lalu mulai
ShowWindow(menang.Handle, WS_MAXIMIZE);
hasil := benar;
akhir
hasil lain := salah;
akhir;
prosedur RestoreDisplay (menang: TWinControl);
mulai
UbahPengaturan Tampilan(PDEVMODE(0)^, 0);
ShowWindow(menang.Handle, SW_RESTORE);
akhir;