Pendahuluan .NET Compact Framework adalah API yang luar biasa, jika bukan yang terbaik, untuk perangkat seluler. Mesin grafisnya sangat dibatasi untuk meningkatkan kecepatan rendering dan mengurangi konsumsi memori. Namun, tampaknya hal ini masih jauh dari memenuhi permintaan pengguna yang terus meningkat akan pengalaman grafis yang lebih baik. Mencoba mendapatkan beberapa kemampuan rendering grafik vektor tingkat lanjut di .NET Compact Framework bisa menjadi tugas yang membosankan. Pengembang memiliki dua opsi:
1. Beralih ke kode asli. Misalnya, Pocket PC Game API mungkin merupakan pilihan yang baik. Performanya sangat mengesankan. Untuk informasi lebih lanjut, lihat artikel yang sangat komprehensif di: http://msdn.microsoft.com/mobility/samples/default.aspx?pull=/library/en-us/dnnetcomp/html/gmangame . Masalahnya adalah kode asli tidak mendukung rendering grafik vektor dan tidak kompatibel dengan beberapa perangkat. Selain itu, ini mungkin tidak berfungsi dengan emulator Pocket PC. Bisa dibayangkan betapa sulitnya men-debug program semacam itu.
2. Harap tunggu hingga mesin grafis seluler generasi berikutnya keluar. Sejauh yang saya tahu, Windows CE 5 akan berisi mesin Direct3D Mobile yang kuat. Ini adalah kabar baik bagi pengembang game seluler, tetapi Direct3D tidak cocok untuk grafik dua dimensi. Ini terlalu rumit untuk digunakan dalam aplikasi umum.
Yang kita butuhkan adalah mesin grafis 2D yang kuat dan mudah digunakan seperti GDI+. Oleh karena itu, saya mengembangkan proyek XrossOne GDI+ dari awal. Itu seluruhnya ditulis dalam kode terkelola C# dan tidak berisi kode asli atau tidak aman. Setelah kerja keras selama berbulan-bulan, akhirnya saya dapat memberikan versi asli yang dapat diunduh di awal artikel ini.
Memulai Dari awal proyek ini, saya selalu berpikir bahwa mesin XrossOne GDI+ harus netral di berbagai perangkat dan platform genggam. Hasilnya, kompatibel dengan Pocket PC, Windows CE, Smartphone, Windows .NET dan Mono. Anda dapat menyalin runtime yang sama ke target yang berbeda dan itu akan tetap berfungsi dengan baik.
Tabel berikut merangkum keseluruhan arsitektur.
Lapisan namespaceXrossOne GDI+ API XrossOne.Drawing
Mesin grafis dua dimensi berbasis titik tetap XrossOne.DrawingFP
16.16 Mesin penghitungan titik tetap XrossOne.FixedPoint
Ada tiga lapisan di XrossOne GDI+. Level terendah adalah "mesin komputasi titik tetap 16,16". Salah satu kelas utama—MathFP—diadaptasi dari perpustakaan Beartronics J2ME. Beberapa fungsi telah dioptimalkan, termasuk sqrt, atan, dan PointFP.Distancecalculation. Di bawah namespace XrossOne.FixedPoint, ada tiga kelas lainnya: SingleFP, DoubleFP, dan MatrixFP. SingleFP adalah kelas Helper untuk 16,16 nomor titik tetap. Ini memberikan kemudahan untuk mengkonversi antara tipe titik tetap dan tipe standar (int, float, string). MatrixFP ditulis untuk transformasi 2D titik tetap. Karena penghitungan titik tetap kurang tepat, beberapa keakuratan mungkin hilang dengan transformasi berjenjang. Misalnya, dalam banyak kasus, dua operasi inversi tidak dapat mengembalikan matriks asli. DoubleFP ada untuk melengkapi perpustakaan, tetapi belum digunakan.
"Mesin grafis dua dimensi berbasis titik tetap" adalah inti dari XrossOne GDI+. Ini mengimplementasikan banyak algoritma grafik vektor yang kompleks, seperti gambar anti-alias, hiasan garis/sambungan, transformasi 2D, pengisian gradien, pengomposisian saluran alfa, dan banyak lagi. Sebagian besar fitur lanjutan di GDI+ asli dapat ditemukan di sini. Namun, Anda sebaiknya hanya menggunakannya secara langsung dalam beberapa kasus karena antarmuka berbasis titik tetapnya tidak ramah pemrogram, namun jangan terlalu khawatir tentang situasi ini. Tersedia API yang dikemas dengan baik. Anda dapat menemukannya di namespace XrossOne.Drawing. Kelas-kelas di XrossOne.Drawing sangat mirip dengan kelas-kelas di System.Drawing, hanya saja setiap kelas memiliki tanda "X" di akhir. Misalnya, kelas XrossOne.Drawing.PenX setara dengan System.Drawing.Pen. Ada sedikit trik untuk mengubah program GDI+ menjadi XrossOne GDI+. Di bagian penggunaan, ganti nama kelas XrossOne GDI+ menjadi kelas yang setara. Misalnya:
menggunakan Pen = XrossOne.Drawing.PenX;
menggunakan LinearGradientBrush = XrossOne.Drawing.LinearGradientBrushX;
menggunakan Matriks = XrossOne.Drawing.MatrixX;
Fitur Utama Gambar Grafik Vektor Anti-Alias
Semua jenis bentuk geometris dua dimensi dapat dirender melalui XrossOne Mobile GDI+, seperti segmen garis, persegi panjang, poligon, elips, sektor, spline Bezier, spline kardinal, dll. Namun, sektor, spline Bezier, dan spline radix tidak tersedia di .NET Compact Framework. Selain itu, semua grafik secara otomatis anti-alias saat dirender. Ini membantu mencapai kualitas super halus. Di .NET Compact Framework, lebar kuas ditetapkan menjadi 1 piksel. Batasan ini tidak ada di XrossOne GDI+. Berbagai ukuran kuas dapat diterapkan pada garis luar semua bentuk, seperti yang ditunjukkan pada Gambar 1.
Gambar 1. Gambar grafik vektor anti-alias
Contoh kode 1
//Hapus latar belakang dan setel ulang status transformasi
gx.Clear(Warna.Putih);
gx.ResetTransform();
//Gambar kotak miring sebagai latar belakang
Pena PenX = PenX baru(Utils.FromArgb(0x40, Color.LightGray), 5);
untuk (int i = -Tinggi; i < Lebar + Tinggi; i+=20)
{
gx.DrawLine(pena, i, 0, i + Tinggi, Tinggi);
gx.DrawLine(pena, i, 0, i - Tinggi, Tinggi);
}
//Gambarlah persegi panjang DarkMagenta dengan pena 10,5 piksel
Warna c = Utils.FromArgb(0x80, Color.DarkMagenta);
pena = PenX baru(c, 10.5f);
gx.DrawRectangle(pena, 50, 20, 150, 200);
//Isi persegi panjang HijauKuning
c = Utils.FromArgb(0xA0, Warna.HijauKuning);
KuasX kuas = SolidBrushX baru(c);
gx.FillRectangle(sikat, 120, 50, 90, 150);
//Gambar elips BlueViolet dengan pena 10,5 piksel
c = Utils.FromArgb(0x80, Warna.BlueViolet);
pena = PenX baru(c, 10.5f);
gx.DrawEllipse(pena, 50, 20, 150, 80);
//Isi elips Merah
c = Utils.FromArgb(0xA0, Warna.Merah);
sikat = baru SolidBrushX(c);
gx.FillEllipse(sikat, 20, 50, 80, 150);
//Gambarlah pai HotPink dari 156,5 derajat hingga -280,9 derajat
pen.Color = Utils.FromArgb(0xA0, Color.HotPink);
gx.DrawPie(pena, 3.6f, 120.3f, 200.8f, 130.1f, 156.5f, -280.9f);
//Gambar kurva Orange Bezier
c = Utils.FromArgb(0xA0, Warna.Oranye);
pena = PenX baru(c, 16);
Poin awal = Poin baru(70, 100);
Kontrol poin1 = Poin baru(100, 10);
Kontrol titik2 = Poin baru(150, 50);
Poin end1 = Poin baru(200, 200);
Kontrol poin3 = Poin baru (100, 150);
Kontrol poin4 = Poin baru (50, 200);
Poin end2 = Poin baru(10, 150);
Titik[] bezierPoints ={mulai, kontrol1, kontrol2, akhir1, kontrol3, kontrol4, akhir2};
pena.EndCap = LineCapX.Round;
gx.DrawBeziers(pena, bezierPoints);
//Menyegarkan
Batalkan();
Output grafik vektor XrossOne GDI+ dan GDI+ asli identik, kecuali radix splines. Algoritma saya diambil dari artikel Algoritma Pemulusan Menggunakan Kurva Bezier oleh Jean-Yves Queinec. Oleh karena itu, Anda mungkin menemukan beberapa perbedaan antara keluarannya, seperti yang ditunjukkan pada Gambar 2 di bawah.
Gambar 2. Output dari DrawCurve/DrawClosedCurve
Meskipun sebagian besar fungsi rendering grafik vektor telah diterapkan, masih ada beberapa pekerjaan yang perlu dilakukan. Beberapa fungsi (DrawString, DrawImage, DrawPath, dll.) tidak akan tersedia hingga versi berikutnya.
pengisian gradien
Ada lima kuas di GDI+ asli—SolidBrush, LinearGradientBrush, PathGradientBrush, TextureBrush, dan HatchBrush. Namun pada versi ini hanya SolidBrush dan LinearGradientBrush yang tersedia. XrossOne GDI+ mendukung RadialGradientBrush tetapi tidak mendukung PathGradientBrush. Gambar 5 di bawah menunjukkan pengisian gradien.
Gambar 5. Isian gradien
Contoh kode 4
//Hapus latar belakang dan setel ulang status transformasi
gx.Clear(Warna.Putih);
gx.ResetTransform();
//Isi persegi panjang dengan LinearGradientBrushX hitam-putih
Persegi Panjang r = Persegi Panjang baru(20, 50, 300, 100);
Warna c1 = Warna.Hitam;
Warna c2 = Warna.Putih;
BrushX brush1 = LinearGradientBrushX baru(r, c1, c2, 30F);
gx.FillRectangle(sikat1, r);
//Isi persegi panjang dengan LinearGradientBrushX 7 warna
r = Persegi Panjang baru(90, 100, 150, 100);
LinearGradientBrushX br = new LinearGradientBrushX(r,Warna.Hitam,Warna.Hitam, 60F);
ColorBlendX cb = ColorBlendX baru();
cb.Positions=pelampung baru[7];
ke dalam saya=0;
untuk(mengambang f=0;f<=1;f+=1.0f/6)
cb.Posisi[i++]=f;
cb.Colors=Warna baru[]
{Warna.Merah,Warna.Oranye,Warna.Kuning,Warna.Hijau,Warna.Biru,Warna.Indigo,Warna.Violet};
br.InterpolasiWarna=cb;
gx.TranslateTransform(160, 10);
gx.RotateTransform(60F);
gx.FillRectangle(br, r);
//Isi persegi panjang dengan RadialGradientBrushX 7 warna
rY += 50;
RadialGradientBrushX brush2 = RadialGradientBrushX baru(r, Warna.Hitam,Warna.Hitam, 220F);
kuas2.InterpolasiWarna = cb;
gx.RotateTransform(-45F);
gx.TranslateTransform(-200, -170);
gx.FillRectangle(sikat2, r);
//Menyegarkan
Batalkan();
Pengomposisian saluran alfa
Struktur Warna di namespace System.Drawing tersedia di .NET Framework dan .NET Compact Framework. Perbedaannya adalah komponen alpha dinonaktifkan dan nilai Hue-Saturation-Brightness (HSB) tidak tersedia di .NET Compact Framework. Untungnya, pengomposisian saluran alfa berfungsi sempurna dengan XrossOne GDI+ (seperti yang mungkin Anda simpulkan dari contoh grafik sebelumnya).
pertunjukan 3,505 mdtk 1,602 mdtk 118,8 % DrawCurve 4,006 mdtk 1,402 ms 185,7% DrawPie 6,810 mdtk 2,003 mdtk 240,0% TranslateTransform 10,615 3,405 mdtk Transformasi mdtk 0,801 mdtk 412,6 % RotateTransform 7,811 ms 1,803 ms 333,2% LinearGradien ( 1) 9,013 ms 2,103 ms 328,6% LinearGradien (2) 8,012 ms 1,803 ms 344,4 %
Memang benar bahwa CPU PC genggam seringkali kurang bertenaga dibandingkan CPU PC standar. Perhitungan yang berat dapat membuat perangkat genggam menjadi kurang responsif, sehingga dapat membuat pengguna frustasi. Dengan kata lain, kinerja sangat penting untuk perangkat lunak perangkat genggam. Oleh karena itu, sebelum menggunakan XrossOne Mobile GDI+ dalam situasi besar, Anda mungkin ingin menganalisis kinerjanya secara keseluruhan. Karena sebagian besar fungsi setara di GDI+ untuk .NET Compact Framework tidak tersedia, tolok ukur dilakukan antara XrossOne Mobile GDI+ dan GDI+ untuk .NET Framework. Pengujian dilakukan dalam kategori berikut: rendering grafik vektor, transformasi 2D, dan pengisian gradien. Skenario pengujian dijalankan dalam kondisi yang sama. Anda dapat menemukan program benchmark dalam paket unduhan, dan Anda dapat dengan cepat melihat keluaran grafisnya di http://www.xrossone.com/projects.php?menu=4.
XrossOne Mobile GDI+ seluruhnya ditulis dalam kode terkelola C#, dan performa keseluruhannya dapat diterima (lihat tabel di bawah), meskipun transformasi 2D dan pengisian gradien memerlukan pengoptimalan lebih lanjut di versi mendatang.
Solusi 66,7 % DrawBezier mdtk 2 Skala 11,7% 4,106