PDA

Tam Sürümünü Görmek İçin : AntiFlickering : Refresh Rate i Ogrenmek ve Double-Buffering Yontemleri (Win32)


Akın Öcal
04/02/2006, 04:07
Merhabalar , sorularimla ilgilecekle simdiden tesekkurler.

Sorularim cikis kaynagi : OpenGL ve DirectX gibi kütüphaneler her türlü refresh rate e gore ekranda flickering i yani titremeyi onleyebiliyor
Zannedersem refresh rate e gore double-buffer yaptiriliyor (yanlis biliyor olabilirm ) Bu kütüphaneler bu isi nasil yapiyor u merak ediyorum Sorularim ise : (Umarim yukardakiler dogrudur yoksa sorular gecersiz olacaK :) )

1) O andaki monitörün calistigi refresh rate i yani hertz i nasil ogrenirim ?

2) MSDN den arastirdigim kadariyla win32api altinda gdi ile double bufffer icin
HDC memDC = CreateCompatibleDC ( hDC );
HBITMAP memBM = CreateCompatibleBitmap ( hDC, nWidth, nHeight );
SelectObject ( memDC, memBM );
gibi bir kod var ( grafik kütüphanelerinden uzagimdir .net de bile basit gdi+ i ogrenmeye tenezül etmedim :) )
Ben 1. adimda ogrendigim refresh rate bilgisine gore double buffer icin yukardaki kodda hangi parametreler ile oyniyacagim nWidth ve nHeight mi ? ( Sonucta hDC zaten bir device context...)

3) Bu sorum en basit olani : adam gibi win32api bildigimi soleyemem
diyelim ki ben ekranda tv deki borsa yazilari gibi sagdan sola akan bir scroll yapmak istiyorum bana bunu yapabilecek en basit gdi kodu ve 2. adimdaki double-buffer kodunun bu gdi objesine nasil uygulandigini bilgisini verebilir misiniz ?

Saygılarımla...


mr1yh1
01/05/2006, 12:05
double-buffering genelde compononent( Canvas, üzerine çizim yaptığın nesne) bazında desteklidir.
Bizim alt düzey işlemlerle uğraşmamıza gerek yoktur.

java swing de var, incelediğim büyük küçük C++ GUI API lerinin hemen hepsinde vardı.
ben opengl ile kullandım( glut ile ), pencereyi oluştururken geçilen sadece bir fonksiyon parametresi ile halloluyordu.
belki bu sayfa yardımcı olabilir.
http://www.martnet.com/~jfosler/articles/WindowsFormsPainting.htm


problem şu: grafikkartı ekran görüntüsü için belleği okuyor.
fakat biz hesaplamalar + belleğe "çizim" yaparken o kadar zaman harcıyoruz ki , biz yazmayı bitirmeden bellek birkaç kez okunuyor.
çözüm: 2 tane sayfa var , çizim geri plandaki bellek bölgesine yapılıyor. bu sırada diğer sayfa ekranda...
"swap buffers" gerçekleştiğinde ekran kartı ikinci sayfayı okuyor bu sırada biz ilk sayfaya yazabiliyoruz.

Sabahi
02/05/2006, 10:14
Hernekadar flickering refresh rate ile ilgili olsada titreme manasina gelmez. CRT ekranlarda 60Hz LCD lerde 75Hz un altinda vertical refresh rate olursa image frame ler arasinda bir solma gozlenir buna flickering deniyor yanlis hatirlamiyorsam. Display properties'den refresh rate ayarlanabildigine gore, bir ihtimal registry'den bulunabilir bu deger. Bide EnumDisplaySettings api fonksiyonunu bir arastirin. Tabi bence cok gerekmedikce bu ayarlarla oynamaniz gerekmez. Double buffering'e gelince yapmak istediginiz flipping bir baska deyisle page flipping yanilmiyorsam. Bunun amaci tearing (yirtilma) dedigimiz olayin onune gecmek. Gdi yada openGL kullanmadim ama DirectX ten ornek vermek gerekirse kullandiginiz versiyonuna bagli ufak tefek degisikler olmakla beraber DirectDraw Surface arayuzunu kullanabilirsiniz tabii biraz eskide kaldi. WaitForVerticalBlank fonksiyonu ise aldigi parametreye bagli olarak flip in vertical refresh rate ile senkronize edilmesine yardimci olur.
Herneyse bence eger baskalarinin yazdigi isinizi gorecek hazir kutuphaneler bulamazsaniz DirectX ve OenGL sizin icin uzun bir ogrenme gerektirecektir. GDI ise hem slow olacak hemde page flipping yapildigini zannetmiyorum GDI+ belki? Bence yuksek seviyedeki dillerle cok daha kolay olarak ayni seyi yapabilirsiniz. Visual basic, .net grubu v.s.