1. คำนำ:
สำหรับ Delphi หากคุณต้องการวาดภาพ คุณต้องประมวลผลก่อน และคุณต้องอ้างอิงหน่วยอื่น ๆ ที่ไม่รวมอยู่ใน Delphi ดังนั้นคุณต้องดาวน์โหลด Gl.pas แยกต่างหาก หน่วย OpenGl ที่พบได้ทั่วไปบนอินเทอร์เน็ตนั้นถูกห่อหุ้มไว้ในเวอร์ชัน 1.0 และจะไม่มีการประกาศฟังก์ชันนี้ สามารถดูหน่วย Gl.pas ได้ทางออนไลน์ นอกจากนี้ จำเป็นต้องมีหน่วย Glaux.pas และ gaux.dll ซึ่งเป็นไลบรารีเสริม จะมีการดาวน์โหลดไว้ท้ายบทความนี้
2. กระบวนการดำเนินการ:
การวาดภาพต้องใช้กระบวนการดังต่อไปนี้ รูปวาดของ Window จะขึ้นอยู่กับบิตแมป เช่น PNG, jpg ฯลฯ เมื่อวาด มันสามารถแปลงเป็น bmp แล้ววาดได้
1. โหลดอิมเมจ bmp: ใช้ auxDIBImageLoadA หรือฟังก์ชันอื่น ๆ
2. แปลงเป็นพื้นผิว: glGenTextures -> glBindTexture -> glTexImage2D, glTexParameteri ใช้เพื่อตั้งค่าพารามิเตอร์ที่เกี่ยวข้อง
3. วาดพื้นผิว: glBindTexture -> glBegin(GL_QUADS) -> glTexCoord2f -> glVertex2f -> glEnd
3. วาดโดยใช้ฟังก์ชัน glDrawPixels
glDrawPixels มีพารามิเตอร์ 5 ตัวดังต่อไปนี้:
width: ความกว้างของภาพตาราง
height: ความสูงของภาพตาราง
รูปแบบ: รูปแบบการจัดเก็บข้อมูลของภาพตาราง
ประเภท: ไม่ทราบ
พิกเซล: ตัวชี้ไปยังข้อมูล DIB
รหัสตัวอย่างจะเป็นดังนี้:
ขั้นตอน TForm1.Draw;var Bmp: TBitmap;begin Bmp := TBitmap.Create; Bmp.LoadFromFile(ExtractFilePath(ParamStr(0)) + '1.bmp'); // ล้างบัฟเฟอร์ glClear(GL_COLOR_BUFFER_BIT หรือ GL_DEPTH_BUFFER_BIT); / ข้อมูลรูปภาพของ TBitmap จะถูกจัดเก็บอย่างต่อเนื่องในหน่วยความจำในลำดับย้อนกลับ ที่อยู่แรกซึ่งเป็นที่อยู่บัฟเฟอร์รูปภาพสามารถรับได้ผ่าน TBitmap.ScanLine[TBitmap.Height-1] // สีของรูปภาพ bmp คือ เก็บไว้ใน bgr ดังนั้นคุณต้องเลือก GL_BGR_EXT เป็นพารามิเตอร์ glDrawPixels(Bmp.Width, Bmp.Height, GL_BGR_EXT, GL_UNSIGNED_BYTE, Bmp.ScanLine[Bmp.Height - 1]); SwapBuffers(FDC);
คุณไม่จำเป็นต้องเปิดใช้งานการแมปพื้นผิวเพื่อวาดภาพโดยใช้วิธีการข้างต้น คุณสามารถใช้ฟังก์ชัน glPixelZoom เพื่อซูมภาพได้ ตำแหน่งที่แสดงอยู่ที่มุมซ้ายล่างของหน้าต่าง (ฉันไม่รู้วิธีเปลี่ยนรูปภาพ) ตำแหน่งในขณะนั้น)
3. ใช้การวาดพื้นผิว
หากคุณต้องการควบคุมตำแหน่งการแสดงและการซูมภาพ คุณสามารถใช้วิธีการต่อไปนี้
1. ตามกระบวนการ ขั้นแรกเราจะโหลดรูปภาพลงในโปรแกรมและรับข้อมูลรูปภาพที่เกี่ยวข้อง
หากต้องการโหลดรูปภาพลงในพื้นผิว โปรดดูที่ไซต์นี้://www.VeVB.COm/article/52125.htm
การโหลดบิตแมปใน Delphi นั้นง่ายมาก และสามารถโหลดได้ด้วยวิธีต่อไปนี้:
(1) โหลดรูปภาพผ่านฟังก์ชัน auxDIBImageLoadA ของไลบรารีเสริม ค่าที่ส่งคืนคือตัวชี้ข้อมูล PTAUX_RGBImageRec และรูปแบบข้อมูล DIB คือ RGB
// โครงสร้างข้อมูล RGB TAUX_RGBImageRec = ขนาดบันทึก .bmp ')); // จะปล่อย p ได้อย่างไร? ทั้ง Dispose และ Freemem ไม่สามารถใช้งานส่วนท้ายของตัวชี้นี้ได้
(2) โหลดรูปภาพผ่าน TBitmap.LoadFromFile Delphi มาพร้อมด้วย จากการเปรียบเทียบประสิทธิภาพ ประสิทธิภาพจะเหมือนกับ auxDIBImageLoadA แต่รูปแบบข้อมูล DIB คือ BGR และตัวชี้ DIB คือ TBitmap.ScanLine[Bmp.Height - 1]
var Bmp: TBitmap;begin Bmp := TBitmap.Create; TBitmap.LoadFromFile(ExtractFilePath(ParamStr(0)) + '1.bmp'); // ทำอะไรสักอย่าง // ปล่อย Bmp.Free;end;
2. สร้างพื้นผิว รวมถึง glGenTextures และ glBindTexture ใน Gl.pas
// สร้างพื้นที่พื้นผิว glGenTextures(1, @texture); // ผูกพื้นที่พื้นผิว glBindTexture(GL_TEXTURE_2D, texture); // ใช้บิตแมปเพื่อสร้างพื้นผิวรูปภาพ glTexImage2D( GL_TEXTURE_2D, // พื้นผิวเป็นพื้นผิว 2D GL_TEXTURE_2D 0, // ระดับรายละเอียดภาพเริ่มต้นที่ 0 3, // จำนวนส่วนประกอบของข้อมูล เนื่องจากรูปภาพประกอบด้วยสีแดง เขียว และน้ำเงิน ค่าเริ่มต้นคือ 3 Bmp.Width // ความกว้างของพื้นผิว Bmp.Height // ความสูงของพื้นผิวคือ 0 / / ค่าของเส้นขอบคือ 0 โดยค่าเริ่มต้น GL_BGR_EXT, // รูปแบบข้อมูล bmp ใช้ bgr GL_UNSIGNED_BYTE, // ข้อมูลที่ประกอบเป็นรูปภาพนั้นเป็นประเภทไบต์ที่ไม่ได้ลงนาม Bmp.ScanLine[Bmp.Height - 1] // DIB data ตัวชี้); // สองบรรทัดต่อไปนี้ให้ opengl ใช้วิธีการกรองที่ OpenGL ใช้ในการขยายพื้นผิวดั้งเดิม (GL_TEXTURE_MAG_FILTER) หรือลดขนาดพื้นผิวดั้งเดิม (GL_TEXTURE_MIN_FILTER) // GL_LINEAR ใช้การกรองเชิงเส้นเพื่อทำให้การประมวลผลภาพราบรื่น แต่ต้องใช้หน่วยความจำเพิ่มเติมและ CPU glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); // การกรองเชิงเส้น glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
3. วาดพื้นผิว
ก่อนที่จะวาดพื้นผิว จะต้องแจ้ง OpenGL เพื่อเปิดใช้งานการแมปพื้นผิว glEnable(GL_TEXTURE_2D) เมื่อเปิดใช้งาน การวาดภาพที่ไม่ใช่พื้นผิวจะไม่ทำงาน อย่าลืมปิดเมื่อคุณใช้งานเสร็จแล้ว
// ต่อไปนี้คือการวาดภาพโดยใช้รูปสี่เหลี่ยมเพื่อวาดภาพ // เปิดใช้งานการแมปพื้นผิวถ้า glIsEnabled(GL_TEXTURE_2D) = 0 จากนั้น glEnable(GL_TEXTURE_2D); // ล้างบัฟเฟอร์ glClear(GL_COLOR_BUFFER_BIT หรือ GL_DEPTH_BUFFER_BIT); := 10; w := 200; // ขยายภาพเป็น 200*200 // เลือกพื้นผิวหลายพื้นผิว ไม่สามารถผูกพื้นผิวระหว่าง glBegin() และ glEnd() glBindTexture(GL_TEXTURE_2D, texture); glBegin(GL_QUADS); ของ glTexCoord2f พารามิเตอร์หนึ่งตัวคือพิกัด X // 0.0 คือด้านซ้ายของพื้นผิว 0.5 คือจุดกึ่งกลางของพื้นผิว และ 1.0 คือด้านขวาของพื้นผิว //พารามิเตอร์ตัวที่สองของ glTexCoord2f คือพิกัด Y // 0.0 คือด้านล่างสุดของพื้นผิว 0.5 คือจุดกึ่งกลางของพื้นผิว และ 1.0 คือด้านบนของพื้นผิว glTexCoord2f(0, 1); glTexCoord2f(l, t); glTexCoord2f( 0, 0); glVertex2f(l, t + w); glEnd();
การวาดภาพด้านบนสิ้นสุดลงแล้ว ต่อไปนี้เป็นโค้ดที่สมบูรณ์ใน Draw คุณไม่จำเป็นต้องอ้างอิงไลบรารีเสริม Glaux.pas
ขั้นตอน TForm1.Draw;var Bmp: TBitmap; texture: GLuint; l, t, w: Integer;begin Bmp := TBitmap.Create; Bmp.LoadFromFile(ExtractFilePath(ParamStr(0)) + '1.bmp'); / สร้างพื้นที่พื้นผิว glGenTextures(1, @texture); // ผูกพื้นที่พื้นผิว glBindTexture(GL_TEXTURE_2D, texture); // ใช้บิตแมปเพื่อสร้างพื้นผิวรูปภาพ glTexImage2D( GL_TEXTURE_2D, // พื้นผิวเป็นพื้นผิว 2D GL_TEXTURE_2D 0, // ระดับรายละเอียดของภาพเริ่มต้นที่ 0 3, / / จำนวนองค์ประกอบของข้อมูล เนื่องจากรูปภาพประกอบด้วยสีแดง เขียว และน้ำเงิน ค่าเริ่มต้นคือ 3 Bmp.Width, // ความกว้างของพื้นผิว Bmp.Height, // ความสูงของพื้นผิวคือ 0, // ค่าของเส้นขอบเริ่มต้นที่ 0 GL_BGR_EXT, // รูปแบบข้อมูล bmp ใช้ bgr GL_UNSIGNED_BYTE, // ข้อมูลที่ประกอบเป็นรูปภาพ คือประเภทไบต์ที่ไม่ได้ลงนาม Bmp.ScanLine[Bmp .Height - 1] // DIB data pointer); สองบรรทัดต่อไปนี้ให้ opengl ใช้วิธีการกรองที่ OpenGL ใช้ในการขยายพื้นผิวดั้งเดิม (GL_TEXTURE_MAG_FILTER) หรือลดขนาดพื้นผิวดั้งเดิม (GL_TEXTURE_MIN_FILTER) // GL_LINEAR ใช้การกรองเชิงเส้นเพื่อทำให้การประมวลผลภาพราบรื่น แต่ต้องใช้หน่วยความจำเพิ่มเติมและ CPU glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); // การกรองเชิงเส้น glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // การกรองเชิงเส้น ต่อไปนี้คือการวาดภาพโดยใช้รูปสี่เหลี่ยมเพื่อวาดภาพ // เปิดใช้งานการแมปพื้นผิวหาก glIsEnabled(GL_TEXTURE_2D) = 0 จากนั้น glEnable(GL_TEXTURE_2D); // ล้างบัฟเฟอร์ glClear(GL_COLOR_BUFFER_BIT หรือ GL_DEPTH_BUFFER_BIT); l := 10; 10; w := 200; ขยายภาพเป็น 200*200 // เลือกพื้นผิวหลายพื้นผิว ไม่สามารถผูกพื้นผิวระหว่าง glBegin() และ glEnd() glBindTexture(GL_TEXTURE_2D, texture); glBegin(GL_QUADS); ของ glTexCoord2f พารามิเตอร์หนึ่งตัวคือพิกัด X // 0.0 คือด้านซ้ายของพื้นผิว 0.5 คือจุดกึ่งกลางของพื้นผิว และ 1.0 คือด้านขวาของพื้นผิว //พารามิเตอร์ตัวที่สองของ glTexCoord2f คือพิกัด Y // 0.0 คือด้านล่างสุดของพื้นผิว 0.5 คือจุดกึ่งกลางของพื้นผิว และ 1.0 คือด้านบนของพื้นผิว glTexCoord2f(0, 1); glTexCoord2f(l, t); glTexCoord2f( 0, 0); glVertex2f(l, t + w); glEnd(); Bmp.Free; SwapBuffers(FDC);สิ้นสุด;
สามารถดาวน์โหลดโค้ดที่สมบูรณ์สำหรับตัวอย่างนี้ได้ที่นี่