Do�ru
Par�alar�n� �izimi
Daha �nce OpenGL alt�nda basit baz� poligonlar�n �izimini g�rm��t�k.
OpenGL sadece birka� basit geometrik �eklin �izimini destekliyor: nokta,
do�ru, poligon ve k���k d�rtgensel veya ��gensel yaylarla tan�mlanm��
y�zeyler gibi.
OpenGL'in basitli�inin ard�ndaki ana fikir bu basit nesnelerden,
kar���k nesnelere do�ru geli�tirimin geli�tiriciye b�rak�lm��
olmas�d�r. OpenGL noktalar�n, do�rular�n ve poligonlar�n
detaylar�n� kontrol etmek i�in komutlar i�erir.
�rnek olarak noktan�n b�y�kl��� piksel olarak glPointSize
ile a�a��daki kullan�m �ekliyle belirlenir:
void glPointSize(GLfloat size)
Noktan�n benimsenmi� de�er olarak b�y�kl��� 1 dir ve size
daima 0'dan b�y�k olmal�d�r. �zet olarak noktan�n b�y�kl��� ondal�kl�
say�larla ifade edilir. Nokta ve do�ru b�y�kl�klerinde oransal (fractional)
de�erlere izin verilir. OpenGL oransal piksel b�y�kl�kleri g�r�nt�le�tirim
i�eri�ine (rendering context) g�re yorumlar. E�er basamak g�r�nt� giderici
(anti-aliasing) mod etkinse, OpenGL kom�u pikselleri ilgilenilen do�ruya
uyacak �ekilde d�zeltir ve oransal geni�lik g�r�n�m�n� vermeye �al���r.
Basamak g�r�nt� giderimi (anti-aliasing), do�rular�n d���k ekran
��z�n�rl���nde g�sterdi�i �irkin y�ld�zlar� ortadan kald�rmak i�in
geli�tirilen bir tekniktir. E�er bu y�ntem uygulanam�yorsa
glPointSize size'� en yak�n tamsay�ya yuvarlatacakt�r.
Fiziksel olarak bir pikselin b�y�kl��� ayg�ta ba�l� bir �eydir. �rnek
olarak d���k ekran ��z�n�rl���nde piksel daha geni� olarak ��z�l�r. Benzer
bi�imde, �izici gibi �ok y�ksek ��z�n�rl�kte de, benimsenmi� olan 1
piksellik �izgi hemen hemen g�r�nmez hale gelir. �izgilerinizin ger�ek
geni�li�ini kestirmek istiyorsan�z pikselin ��kt� ayg�t�n�zdaki ger�ek
fiziksel �l�� de�erini bilmeniz gerekmektedir.
�izgilerin geni�li�i glLineWidth fonksiyonu ile belirlenir,
bu komutun glBegin() - glEnd() �ifti aras�nda daha �nceden
�a�r�lm�� olmas� gerekir. Komutun tam s�zdizimi a�a��dad�r.
void glLineWidth(GLfloat width)
OpenGL'de basamak g�r�nt� giderimsiz (nonantialiased) �izgilerin geni�li�i
basamak g�r�nt� giderimli (antialiased) �izgilerin geni�li�inin en yak�n
tamsay�ya yuvarlanm�� en b�y�k de�eriyle s�n�rlanm��t�r. �unu akl�n�zda tutun:
�izgi geni�likleri �izgiye dik olarak �l��lmezler; e�imin mutlak de�erinin
1 den, k���k olmas� durumunda y do�rultusunda, b�y�k olmas� durumunda x
do�rultusunda �l��l�rler.
Bu ay di�er bir basit fakat yararl� 2D animasyonlar� haz�rlam��
bulunuyoruz. Bunlar size �e�itli t�r �izgi kal�nl�klar�n�n OpenGL'de
nas�l kullan�laca��n� g�sterecektir.(../../common/March1998/example2.c,
../../common/March1998/Makefile). Kuvantum fizi�inden bir �rnek, bir kuyu
potansiyel i�inde tutulu kalm�� bir kuvantum par�ac�k se�tim. Niye? H�mmm,
ger�ekte unuttum. Her neyse, bunun fizik ve m�hendislik ��rencilerine
zamana ba��ml� Schroedinger denkleminin nas�l ��z�lebilece�ini g�rmekte
yard�mc� olaca��n� d���nd�m. Di�er bireyler kuvantum mekani�inin �nceden
kestirilemez do�as�n� g�zleyerek e�lenebilirler. Kuvantum Mekani�i'nde
bir par�ac�k, pozisyonu ve h�z� ile de�il bir "dalga" ile, mutlak de�er
karesi, par�ac���n verilen bir konumda (par�al� beyaz do�ru) bulunma
olas�l���n� veren dalga ya da dalga fonksiyonu (bizim animasyonumuzda mor
kal�n �izgi olan) ile temsil edilir:
Figure 1. Quantum Simulation Snapshot
S�radan diferansiyel denklemler hakk�nda baz� kurs �al��malar�nda
bulunanlara s�yledi�im gibi dalga denklemi FFT (H�zl� Fourier D�n���m�)
ayr�k operat�r (split operator) y�ntemi ile integre edilir. Bu metod
di�er sonlu farklar metodlar�ndan daha h�zl� ve do�rudur. Bu y�ntem
do�rusal olmayan dalga yay�l�m�nda da kullan�labilir. Zamansal evrim
operat�r� ikinci ya da daha y�ksek mertebeden olan ve sadece ya konuma
ya da momentuma ba�l� operat�rlere ayr��t�r�l�r. Daha sonra dalga
fonksiyonunun evrimi, bu operat�rlerin ard���k olarak uygulanmalar� ve
bunun i�in de konum ve momentum uzaylar� aras�nda gidi� geli�lerle
sa�lan�r.
Kaynak kodu di�er bir�ok uygulama i�in kullan�labilir. Benim kuvantum
simulasyonumu kendi zamana ba��ml� fonksiyonunuzla de�i�toku� edebilir
ve sisteminizin g�zel animasyonlar�n� elde edebilirsiniz. Kendiniz de,
fonksiyon ve veri dosyalar�n�n grafiklerinin �izimi i�in basitle�tirilmi�
bir OpenGL tabanl� gnuplot yazmay� deneyebilirsiniz.
E�er okuyucu daha �nceki makaleleri takip ettiyse Glut ve OpenGL
�zerindeki kaynak kodlar�n� �ok basit g�r�p kolay anlayacakt�r.
(Tabii ki kuvantum mekani�i bir kenarda tutularak). Burada ola�an�st�
giden bir�ey bulunmamaktad�r. main()'de �ift emicibellekli
(buffer) bir modda pencere a�t�k. Daha sonra, s�ras�yla, dalga
fonksiyonunun grafi�inin �izimini ve denkleminin ��z�m�nden elde
edilmesini sa�layan display() ve idle() geri�a��r�m
(callback) fonksiyonlar�na ge�tik. Her ne kadar bu yaz�n�n i�eri�ini
kavramak i�in �ok g�zel bir aldatmaca olan idle() fonksiyonunda ne oldu�unu
bilmek ille de gerekmiyorsa da siz yine de �nemseyin.
void
display (void)
{
static char label[100];
float xtmp;
/* Clean drawing board */
glClear (GL_COLOR_BUFFER_BIT);
/* Write Footnote */
glColor3f (0.0F, 1.0F, 1.0F);
sprintf (label, "(c)Miguel Angel Sepulveda 1998");
glRasterPos2f (-1.1, -1.1);
drawString (label);
/* Draw fine grid */
glLineWidth (0.5);
glColor3f (0.5F, 0.5F, 0.5F);
glBegin (GL_LINES);
for (xtmp = -1.0F; xtmp < 1.0F; xtmp += 0.05)
{
glVertex2f (xtmp, -1.0);
glVertex2f (xtmp, 1.0);
glVertex2f (-1.0, xtmp);
glVertex2f (1.0, xtmp);
};
glEnd ();
/* Draw Outsite box */
glColor3f (0.1F, 0.80F, 0.1F);
glLineWidth (3);
glBegin (GL_LINE_LOOP);
glVertex2f (-1.0F, -1.0F);
glVertex2f (1.0F, -1.0F);
glVertex2f (1.0F, 1.0F);
glVertex2f (-1.0F, 1.0F);
glEnd ();
/* Draw Grid */
glLineWidth (1);
glColor3f (1.0F, 1.0F, 1.0F);
glBegin (GL_LINES);
for (xtmp = -0.5; xtmp < 1.0; xtmp += 0.50)
{
glVertex2f (xtmp, -1.0);
glVertex2f (xtmp, 1.0);
glVertex2f (-1.0, xtmp);
glVertex2f (1.0, xtmp);
};
glEnd ();
/* Draw Coordinate Axis */
glLineWidth (2);
glBegin (GL_LINES);
glVertex2f (-1.0, 0.0);
glVertex2f (1.0, 0.0);
glVertex2f (0.0, -1.0);
glVertex2f (0.0, 1.0);
glEnd ();
/* Axis Labels */
glColor3f (1.0F, 1.0F, 1.0F);
sprintf (label, "Position");
glRasterPos2f (0.80F, 0.025F);
drawString (label);
glColor3f (1.0F, 0.0F, 1.0F);
sprintf (label, " Quantum Probability ");
glRasterPos2f (0.025F, 0.90F);
drawString (label);
glColor3f (1.0F, 1.0F, 1.0F);
sprintf (label, " Real(Psi) ");
glRasterPos2f (0.025F, 0.85F);
drawString (label);
/* Draw Wavefunction */
psiDraw (NR_POINTS, psi, x);
/* Draw potential Function */
potentialDraw (NR_POINTS, potential, x);
glutSwapBuffers ();
};
�lk olarak renk emicibellek biti (color buffer bit) temizleniyor.
Bu bize temiz (siyah) bir �izim d�zlemi olu�turuyor. glRasterPos ve
glutBitmapCharacter (�izimkatar� renk bak�pse�me [clut=color look
up table] ) olana�� i�in bir sarmalay�c�dan [wrapper] ba�ka bir�ey de�il)
kullan�larak dipnot ekleniyor. Gelecek derslerde glRasterPos
dokular�n g�r�nt�le�tiriminde yine yard�mc� fonksiyon olarak g�z�kecektir.
Ne OpenGL ne de GLUT grafik penceresi �zerinde metin g�r�nt�le�tiriminde
kolay ve g��l� bir yol sa�layabilmektedir. glutBitmapCharacter, temelde,
bir font ikilitabang�sterilimini (bitmap) renk emicibelle�i �zerine
d���r�r.
Dipnotu bir tak�m �izgiler izler: d�� kutu, arka plan �izgisi,
koordinat eksenleri ve tabii ki psiDraw ve potentialDraw
ile olu�turulan e�riler. Her �izgi g�r�nt�le�tirilmeden �nce
glLineWidth komutu do�runun kal�nl���n� piksel say�lar� ile
belirtir. 1. �ekil bir Xwindow sistemindeki (Linux Alpha) ��kt�y�
g�stermektedir. Baz� bilinmeyen nedenlerden dolay� bana g�re windows95
��kt�s� anlams�y bir yap�da gibi g�z�k�yor, sanki antialiasing �zelli�i
SGI OpenGL s�r�c�s� taraf�ndan desteklenmiyor g�r�n�m� veriyor; farkl�
geni�likteki do�rular� ay�rdedilebilir bi�imde g�r�nt�lemek m�mk�n olam�yor,
arka plan kare �rg� (grid) �ok fazla d�zg�n g�z�k�yor. Bu bozukluklar
d���k ��z�n�rl�klerde olma yerine y�ksek ��z�n�rl�klerde olu�uyor.
Linux X pencere sisteminin b�y�k win95/NT sistemini bir kez daha yenilgiye
u�ratmas�ndan dolay� mutluyum.
display() fonksiyonunda iki t�r do�ru g�r�nt�le�tirimi
bulunmaktad�r. D���m noktalar�n� s�rekli bir a��k do�ru ile birle�tiren
GL_LINES modu ve sonunda �evrimi kapatan GL_LINE_LOOP modu.
Do�ru
Par�alar�nda Basamak G�r�nt� Giderimi
Burada reshape() geri�a��r�m fonksiyonunda do�rular
i�in basamak g�r�nt� giderimini etkinle�tirmi� bulunmaktay�m.
void
reshape (int w, int h)
{
glMatrixMode (GL_MODELVIEW);
glLoadIdentity ();
glViewport (0, 0, w, h);
glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
gluOrtho2D (-1.2, 1.2, -1.2, 1.2);
glEnable (GL_LINE_SMOOTH); /* Enable Antialiased lines */
glEnable (GL_LINE_STIPPLE);
};
GL_LINE_STIPPLE ne i�in kullan�l�yor? OpenGL bize sadece �izgi
geni�li�ini de�il ayn� zamanda �r�nt�y� de (pattern) kontrol etmeyi sa�l�yor.
GL_LINE_STIPPLE etkinle�tirilmesi bize tirelerle veya di�er �r�nt�lerle
do�rular �izmemizi sa�lar. Animasyondaki tek kesikli �izgi (stippled line)
psiDraw() fonksiyonunun �iziminde g�z�kmektedir.
glLineWidth (1);
glPushAttrib (GL_LINE_BIT);
glLineStipple (3, 0xAAAA);
glBegin (GL_LINE_STRIP);
for (i = 0; i < nx; i++)
{
xs = ratio1 * (x[i] - XMIN) - 1.0;
ys = ratio2 * (psi[2 * i] - YMIN) - 1.0;
glVertex2d (xs, ys);
};
glEnd ();
glPopAttrib ();
�izgi
Kesiklile�tirimi
glLineStipple kesikli �izgi �iziminde kullan�lacak
�r�nt�y� belirler. Bizim �rne�imizde kullan�lan �r�nt� 0xAAAA d�r. 2'li
d�zende bu mod 0000100010001000 �eklindedir. OpenGL bu �izimi 3 bit bo�,
1 bit dolu, 3 bit bo�, 1 bit dolu, 3 bit bo�, 1 bit dolu ve son olarak
4 bit bo� bi�iminde yorumlar. Evet, �r�nt� geriye do�ru okunur, ��nk�
ilk �nce d���k mertebeden bit'ler okunur. �imdi glLineStipple
iki parametre �a��racakt�r, onalt�l�k d�zende bir say� olmas� gereken
kesikli �r�nt� ve bu �r�nt�y� �l�eklemek i�in bir tamsay� �arpan.
Dolay�s�yla, bir 3 �arpan�yla, bizim kesikli do�rumuz 9 bit bo�,
3 bit dolu, 9 bit bo�, 3 bit dolu, 9 bit bo�, 3 bit dolu ve son
olarak da 12 bit bo� bi�iminde bir g�r�nt� verecektir. Bu �arpanla ve
ikilitaban �r�nt�lerle oynayarak karma��k yap�daki olas� t�m do�rular�
�izmek m�mk�nd�r.
Bir ayr�nt� daha: Burada kesikli �izgi g�r�nt�le�tirimini push ve pop
deyimleri aras�na ald�m. Birinci yaz�m�zda OpenGL'in bir durum makinas�
oldu�unu belirtti�imizi an�msay�n. Gelecek yaz�lar�m�zda bu push ve pop
i�lemleri �zerinde daha ayr�nt�l� duraca��z, ama k�saca yapt���m�z �eyin
ilk olarak glPushAttrib (GL_LINE_BIT) komutuyla GL_LINE_BIT
durum de�i�keninin (bu de�i�ken kesiklileme �r�nt�s�n� tan�mlar ya da
se�er) o andaki de�erini bir y���t (stack) i�ine yerle�tirmek, daha sonra da
GL_LINE_BIT de�erini glLineStipple komutuyla de�i�tirmek ve
i�imizi bitirdi�imizde GL_LINE_BIT'in ilk de�erini geri getiren
glPopAttrib fonksiyonunu �a��rmak oldu�unu s�yleyebiliriz.
Bu d�zenek (mechanism) OpenGL durum de�i�kenlerinin de�erlerinin
yerel olarak de�i�tirilmesinin etkin bir yoludur. E�er bunu yapmam��
olsayd�k, glLineStipple komutundan sonra �izilen t�m
�izgiler ayn� kesiklileme �r�nt�s�ne sahip olacak ve kendi uygulamam�zdaki
her g�r�nt�le�tirimi yap�lan �izgi i�in bir glLineStipple komutu
kullanmak zorunda kalacakt�k. Push ve Pop bizi bu can s�k�c� duruma
d��mekten korur.
�lerki Zamanda....
OpenGL, 3 Boyutlu API aray�z� nedeniyle �ok �nl�d�r. Buradaki
kadar�yla, biz OpenGL ile 2 Boyutlu baz� temel g�r�nt�le�tirim olanaklar�n�
incelemi� bulunuyoruz. Gelecek kez, 3 Boyutlu OpenGL g�r�n�m�n�, bir
perspektifin nas�l yarat�laca��n�, koordinat sistemlerini, kesmeyle alma
d�zlemlerini (clipping plane) ve izd���m matrislerini inceleyece�iz.
O g�ne dek OGL......ile iyi e�lenceler.
|