Artık pencerelerimizi
şekillendirmenin zamanı geldi mi ne dersiniz? C dilini kullanarak bir OpenGL
penceresinin nasıl oluşturulacağını önceki yazılarımızda ele almıştık. Bu amaçla
geliştirilmiş bir takım araçların nasıl kullanılacağına ilişkin bilgiler ednmiştik.
Artık çizim işlemlerine geçebiliriz. Bu yazımızda penceremize temel geometrik
şekillerin nasıl çizileceğini ve bu şekilleri nasıl renklendireceğimizi göreceğiz.
Bu işlemleri yine OpenGL kütüphanesindeki API fonksiyonlarını kullanarak gerçekleştireceğiz.
Önceki yazılarımızda geliştirdiğimiz uygulamayı, çizim işlemlerini yapan uygulamamız
için bir altlık olarak kullanacağız. Bu nedenle bu yazıyı okumadan önce pencere
oluşturma uygulamasını kavramış olmak işinizi kolaylaştıracaktır. OpenGL’in
çizim amacıyla kullanılan fonksiyonlarını ele almıştık. Çizim uygulamamıza geçmeden
önce bunları hatırlamamız faydalı olacaktır :
void
glBegin(enum kip); |
Bir
çizime başlandığını belirtir. Parametresi çizilen geometrik şekli tanımlar.
Bu parametre yerine geçilmesi gereken sembolik sabitler şunlardır :
   - GL_POINTS => Nokta çizileceğini
belirtir.
   - GL_LINES => Verilen
noktaların birleştirilerek bir çizgi çizileceğini belirtir.
   - GL_POLYGON => Verilen
noktaların birleştirilerek doğrular oluşturulacağını ve oluşan şeklin alansal
bir şekil olacağını, içinin renklendirileceğini belirtir.
   - GL_QUADS => Verilen
dört noktadan içi renkelndirilmiş bir dörtgen oluşturulacağını belirtir.
   - GL_TRIANGLES => Verilen
üç noktadan içi renklendirilmiş üçgen oluşturulacağını belirtir.
   - GL_TRIANGLES_STRIP =>
Verilen noktaların üçer üçer sırasıyla birleştirerek üçgenler oluşturulacağını
belirtir.
   - GL_QUAD_STRIP => Verilen
noktaların dörder dörder sırasıyla birleştirilerek dörtgenler oluşturulacağını
belirtir.
   - GL_TRIANGLE_FAN => Verilen
noktaların ilk nokta ikişer ikişer alınıp her adımda ilk noktayı üçüncü
nokta kabul ederek birleştirileceğini ve yelpazemsi bir şekil oluşturulacağını
belirtir. |
void
glEnd(glVoid); |
glBegin()
fonksiyonu ile başlatılmış çizim işleminin bittiğini belirtir. Çizdirilen
şekil ekrana bastırılmak üzere saklanır. Saklanmış bu şeklin çizdirilmesi
için başka bir fonksiyon kullanılır. |
void
glFlush(glVoid); |
Tampon
bellekteki tüm şekillerin ekrana çizdirilmesini sağlar. |
void
glVertex2f(float x,float y); |
Bir
geometrik şekle ait kontrol noktasının koordinat değerlerini belirtir. Geometrik
şeklin ne olacağı glBegin fonksiyonunun parametresi ile belirlenir. Bu fonksiyon
iki boyutlu çizim yapılacağı zaman kullanılır. Koordinatın sadece x ve y
değerleri verilir. Bu fonksiyon ile aynı işi yapan glVertex2s, glVertex2i,
glVertex2d fonksiyonları sırasıyla short, integer, double türden parametre
değişkenleri alırlar. |
void
glVertex3f(float x,float y,float z); |
Bir
geometrik şekle ait kontrol noktasının koordinat değerlerini belirtir. Geometrik
şeklin ne olacağı glBegin fonksiyonunun parametresi ile belirlenir. Bu fonksiyon
üç boyutlu çizim yapılacağı zaman kullanılır. Koordinatın x ve y değerlerine
ilaveten z değeri de verilir. Bu fonksiyon ile aynı işi yapan glVertex3s,
glVertex3i, glVertex3d fonksiyonları sırasıyla short, integer, double türden
parametre değişkenleri alırlar. |
void
glColor3f(float kirmizi,float yesil,float mavi); |
Çizilecek
şeklin rengini belirler. Ön tanımlı değerler 0’dır. |
void
glRectf(float x1,float y1,float x2,float y2); |
Parametre
olarak geçilen koordinat değerlerini sol alt köşe ve sağ üst köşe olarak
kabul ederek içi dolu bir dikdörtgen çizer. |
Bu fonksiyonlar
temel geometrik şekillerin çizimi için işimizi görecektir. Bu uygulamamızda
iki boyutlu temel geometrik şekilleri çizmeye çalışalım. Bu amaçla, OpenGL çizim
fonksiyonlarının sonu ’2f’ ile biten biçimlerini kullanacağız. Bu fonksiyonlara
geçeceğimiz parametreler ise, geometrik şekillerimize ilişkin kontrol noktalarının
çizim ekranındaki x ve y koordinatlarıdır. Üç boyutlu şekillerin çizilmesi için,
çizim fonksiyonlarından sonu ’3f’ ile bitenler kullanılır. Bu durumda bir de
noktaların z koordinatı değerlerinin hesaplanması gereklidir.
Çizim ekranımızın
tam orta noktası, başlangıç koordinatıdır ve değeri (0,0)’dır. Bu nokta baz
alınarak tüm noktaların koordinat değerlerini hesaplayıp ilgili fonksiyonlara
parametre olarak geçeceğiz. Çizeceğimiz şekiller, üçgen, daire ve karedir. Üçgen
ve kare şekillerini önce içleri boş olarak, sonra içleri dolu olarak (poligon
modunda) çizeceğiz. Çizim ekranımızı önceki uygulamada oluşturmuştuk. Uygulamada
çizim işlemlerinin yapılması gereken fonksiyon DrawGLScene isimli fonksiyondu.
WinMain fonksiyonunda çizim işlemlerini yapması için bu fonksiyonu çağırmıştık.
O halde çizim kodlarını bu fonksiyona yazmalıyız. Önce içi dolu üçgeni çizelim
:
//...
glColor3f(0.2,0.6,0.5);
glBegin(GL_POLYGON);
glVertex2f(-0.25, 0.25);
glVertex2f(-0.75, 0.25);
glVertex2f(-0.5, 0.75);
glEnd(); //... |
glColor3f fonksiyonu
ile çizeceğimiz şeklin rengini belirliyoruz. Bu fonksiyona geçilen parametre
değişkenleri kırmızı, yeşil ve mavi değerlerine karşılık gelir. Bu değerler
değiştirilerek değişik renkler elde edilebilir. glBegin fonksiyonu, bir çizimin
başladığını belirtir. Parametre değişkeninde ise çizilen şeklin geometrisi hakkında
bilgi verilir. Burada biz fonksiyona GL_POLYGON sabitini parametre değişkeni
olarak gönderdik. Bu sayede sonraki adımlarda koordinat değerlerini vereceğimiz
noktalardan geçen kapalı bir şekil oluşturulacak ve içi de glColor3f fonksiyonu
ile belirttiğimiz renge boyanacaktır. Çizim ekranının sol üst köşesinde kalacak
bir üçgen çizdirmek istiyoruz. Buna göre hesapladığımız koordinat değerlerini
glVertex2f fonksiyonu ile belirtiyoruz. Noktalar bittikten sonra glEnd fonksiyonunu
çağırarak çizim işleminin bittiğini belirtiyoruz. Bu kod çalıştığında ekranın
sol üst köşesinee içi dolu bir üçgen çizilecektir. Şimdi üçgenin yanına yine
içi dolu bir dörtgen çizdirelim. Bu amaçla yine köşe noktalarının koordinat
değerlerini vererek GL_POLYGON modunda bir çizim yapabiliriz. Ancak bunun yerine
bu işi otomatik olarak yapan glRectf fonksiyonunu kullanalım :
//... glColor3f(0.8,0.0,0.5);
glRectf(0.25, 0.25, 0.75, 0.75);
//... |
Dörtgenin rengini
glColor3f fonksiyonu ile ayarladıktan sonra glRect fonksiyonunu çağırıyoruz.
Dörtgenin, ekranda sağ üst köşede kalmasını sağlayacak biçimde hesapladığımız
koordinat değerlerini fonksiyona parametre değişkeni olarak geçiyoruz. Şimdi
ekranın tam ortasına bir çember çizelim. Bunun için bir çemberin sınırları üzerinde
dolaşarak 360 tane nokta çizeceğiz. Sonuçta elde ettiğimiz görüntü çemberi oluşturacak.
GLU kütüphanesinde bu işi otomatik olarak yapan gluDisk fonksiyonu bulunmaktadır.
Uygulamada biz bunu kendimiz oluşturacağız :
//...
glColor3f(0.5,0.5,0.5);
glPointSize(5.0);
glBegin(GL_POINTS);
for(i =
1; i < 360; i++) {
    x = 0.25 * sin(((float)i) * 3.14 / 180);
    y = 0.25 * cos(((float)i) * 3.14 / 180);
    glVertex2f(x,y);
} glEnd(); //...
|
Burada yaptığımız
işlemi biraz açıklayalım : Öncelikle çizimimizin rengini glColor3f fonksiyonu
ile belirttik. Daha sonra, glPointSize fonksiyonu ile noktalarımızın çapını
belirttik. Buradaki çap değerini artırırsak çemberin sınırları daha kalın çizilecektir.
Aynı şekilde, çap değerini azaltırsak çemberin sınırları daha ince olacaktır.
Bu fonksiyona çap değeri olarak 5.0 geçiyoruz. Daha sonra glBegin fonksiyonuna
GL_POINTS parametresini geçerek çizime başladığımızı ve nokta çizmek istediğimizi
belirtiyoruz. İzleyen for döngüsü içerisinde, her adımda verilen koordinat değerlerine
birer nokta çizilmektedir. Burada yaptığımız koordinat hesabı, bir çemberin
çevresini gezen bir hesaptır. Çevre üzerinde sırayla 360 tane nokta attığımızda
elde ettiğimiz görüntü bir çember şeklinde olacaktır. Çizdiğimiz tek bir noktanın
görüntüsü çapı belirttiğimiz değer kadar olan bir kare şeklinde olacaktır. Ancak
bu noktaların tamamı bir araya geldiğinde çember elde etmiş olacağız. Burada
sin ve cos fonksiyonlarını kullandığımız için uygulamanın başına mat.h başlık
dosyasını da eklemeliyiz. Şimdi ekranın sol alt kısmına içi boş bir dörtgen
çizdirelim. Bunun için çizime başlarken GL_LINES parametresini geçmeliyiz :
//...
glColor3f(0.2,0.8,1);
glBegin(GL_LINES);
glVertex2f(-0.75, -0.75);
glVertex2f (-0.75, -0.25);
glVertex2f (-0.75, -0.25);
glVertex2f (-0.25, -0.25);
glVertex2f (-0.25, -0.25);
glVertex2f (-0.25,-0.75);
glVertex2f (-0.25,-0.75);
glVertex2f (-0.75,-0.75);
glEnd();
//... |
Çizimin rengini
belirledikten sonra glBegin fonksiyonunu çağırarak GL_LINES parametresini geçiyoruz.
İzleyen adımlarda, ekranın sol alt köşesinde kalacak biçimde bir dörtgenin noktalarının
koordinat değerlerini belirtiyoruz. Bu noktalar ikişer ikişer sırasıyla birbiri
ile birleştirilir. Sonuçta da bir dörtgen elde edilir. Şüphesiz burada daha
fazla noktanın koordinatını belirterek bir çokgen de elde edebiliriz. Aynı şekilde
ekranın sağ alt köşesine bir üçgen çizdirmek için yine GL_LINES parametresini
geçerek çizime başlıyoruz :
//...
glColor3f(0.2,0.0,3);
glBegin(GL_LINES);
glVertex2f(0.5, -0.5);
glVertex2f(0.75, -0.75);
glVertex2f(0.75, -0.75);
glVertex2f(0.25,-0.75);
glVertex2f(0.25, -0.75);
glVertex2f(0.5,-0.5);
glEnd();
//... |
Burada belirttiğimiz
noktalar da ikişer ikişer birleştirilerek bir üçgen elde edilecektir. Uygulamanın
başında içi dolu bir üçgen elde etmek için GL_POLYGON parametresini geçerek
çizime başlamıştık. Uygulamayı çalıştırdığımızda elde etmemiz gereken görüntü
şöyledir :
Aynı uygulamayı
GLUT kütüphanesini kullanarak pencere oluşturduğumuz projede yapmak için tek
yapılması gereken bu uygulamadki çizim kodlarının, GLUT kütüphanesi uygulamasındaki
çizim fonksiyonuna taşınmasıdır. OpenGL kütüphanesi daha birçok fonksiyon içermektedir.
Ayrıca kullanımı kolaylaştıran GLUT kütüphanesinde de birçok fonksiyon vardır.
Bu uygulamada temel geometrik şekillerin çizimi için yukarıda açıkladığımız
fonksiyonlar yeterlidir. Ancak kütüphanedeki diğer fonksiyonlara da yeri geldiğinde
sırasıyla değineceğiz.
Microsoft Visual
C++ 6.0’da hazırlanmış örnek uygulamayı indirmek için buraya tıklayınız. Bir
sonraki yazımızda görüşmek dileğiyle herkese iyi günler dilerim.
Kaynaklar :
- www.nehe.gamedev.net
- OpenGL Yardım Sayfaları
Makale:
C ve OpenGL : Temel Geometrik Şekillerin Çizimi C ve Sistem Programlama Çiğdem Çavdaroğlu
|