C dili ile OpenGL Programlama

merakettim

Homo Sapiens Sapiens
Özel üye
C programlama dili ile OpenGL programlama öğrenmek isteyen arkadaşlara kısıtlıda olsa burada bazı fonksiyonların ne işe yaradığını açıklayacağım.Benden okadar büyük bir randıman beklemeyin çünkü ben de deneme yanılma yöntemi ile ve çok az da anlasam ingilizce kaynaklardan öğrendim.Bu yüzden sadece kendi bildiklerimi anlatacağım.Fazla zamanım olmadığı için fonksiyon fonksiyon işleyeceğiz.
Eveeeet..
Gel gelelim OpenGL nedir?Ne işe yarar?Kim çıkarmış?Niye çıkarmış?
Bu soruları google'dan aratın,yormayın beni.:D

Önce bir başlangıç yapmak lazım.

Her okuduğum yazıda ilk iş boş bir pencere oluşturuyolardı.Biz de böyle yapacağız.

PHP:
#include <GL/glut.h>// bu kütüphaneye alışın;)

void ciz(void)//meşhur "ciz" fonksiyonumuz
{
    glClear(GL_COLOR_BUFFER_BIT);//renk tamponu aktif
}

int main(int argc, char *argv[])//main fonksiyonun sabit parametreleri ve programın başı
{  

    glutInit(&argc, argv);//glut'a initalize edilecek değerler
    glutInitWindowSize(400,400);//pencere boyutları
    glutCreateWindow("Boş Pencere");//oluşturulan pencere,string cinsinden pencerenin adı
    glutDisplayFunc(ciz);//çizimin yapılacağı ön tampon("ciz" isimli fonksiyonda gerçekleşecek)
    glutMainLoop();//işte ekrana basım yapan fonksiyonumuz

    return 0;//program güven ile bitti(hayırlı olsun;))
}

Gördüğünüz gibi boş bir pencere oluşturduk.

Şimdi bu pencereyi daha düşük seviyeli de hazırlayabilirdik.Lakin Win32 programlamış olsaydık.glut.h kütüphanesi bizim için alışılmış kalıp işleri yapıyor.Bu da daha anlaşılır ve küçük kodlar yazarak büyük işler yapmamızı sağlıyor.Bu yüzden glut.h kütüphanesini indirin ve kurun.(Eğer devc++ kullanıyorsanız buradan indirebilirsiniz).

Fonksiyonları açıklayalım.

int main(int argc, char *argv[]);

Bu bir kalıptır.Değiştiremessiniz.Programın başladığı yeri bu şekilde gösterirsiniz.İnt argc ve,char pointer argv bizim uşağımız.Veriler bu argümanlarla gönderilip,alınıyor.

glutInit(&argc, argv);

glut kütüphanesinde işlenmesi için bu şekilde gönderilir.

glutInitWindowSize(400,400);

Kullanım bu şekildedir.Argümanları int cinsinden,geri dönüş değeri ise yoktur(void).

void glutInitWindowSize(int x,int y);

glutCreateWindow("Boş Pencere");

int glutCreateWindow("string");

String cinsinden argüman alır ve int cinsinden pencere numarası ile döner.
Bu fonksiyon ile penceremize isim veririz ve verdiğimiz isimli bir pencere oluştururuz.

glutDisplayFunc(ciz);

void glutDisplayFunc(void fonksiyonunadı(void));

Argümanı fonksiyonun adıdır.Argüman olarak atanacak fonksiyonun kullanım şekli ise void fonksiyonunadı(void) şeklindedir.
Bütün cizim işleri burada yapılır ve ekrana basılmak üzere,ilgili fonksiyonla gönderilir.

glutMainLoop();

İşte asıl ekrana basma işi bu fonksiyon sayesinde gerçekleşir.


*Gelecek yazıda 2 boyutlu ve dop dolu bir pencere yapacağız:)
 

merakettim

Homo Sapiens Sapiens
Özel üye
Dolu bir pencere çizme zamanı şimdi.Önce 2 boyutlu geometrik şekillerle başlayalım işe;

PHP:
#include <GL/glut.h>/**/

void ciz(void)/**/
{ 
    glClear(GL_COLOR_BUFFER_BIT);//renk tamponu kullan
    glBegin(GL_POLYGON);//çizim üçgen olacak
    glColor3f(1,0,0);//renk
    glVertex2f(0,0);//üçgenin bir noktası(0,0)
    glVertex2f(0.5,0);//üçgenin diğer noktası (0.5,0)
    glVertex2f(0.5,0.5);//ve sonuncu noktası (0.5,0.5)
    glEnd();//Gl_POLYGON bitti(üçgen çizimi bitti)
    glFlush();//ekrana basılmak için yolla
} 

int main(int argc, char *argv[])/**/
{    

    glutInit(&argc, argv);/**/
    glutInitWindowSize(400,400);/**/
    glutCreateWindow("Dolu pencere\"iki boyutlu\"");/**/
    glutDisplayFunc(ciz);/**/
    glutMainLoop();/**/

    return 0;/**/
}

Yukardaki örnekte üçgen çizdik.Şimdi fonksiyonlarımızı açıklayalım.

glBegin(GL_POLYGON);

Bu fonksiyon,noktaları nasıl kullanmak istedipimizi belirtmemiz içindir.

void glBegin(sabit); şeklinde kullanılır.Sabitler ise gl.h kütüphanesinde belirtilmiştir ve bunlar:

GL_POLYGON

3 noktayı doğrularla birleştirip üçgen oluşturmak ve bu üçgenin içini boyamak için,

GL_POINTS

Nokta çizmek için,

GL_LINES

Noktaları birleştirip doğru oluşturmak için,

GL_QUADS

4 noktayı doğrularla birleştirip içi boyalı bir dörtgen oluşturmak için,

NOT:Eğer dörtgen oluşturmak istiyorsanız noktaları sırasıyla yazmanız gerekir.
ilk önce sol üst,sağ üst,sağ alt,sol alt olmalı.Aksi halde kelebek gibi olur:D

GL_TRIANGLES

3 noktadan üçgen oluşturmak için,

GL_TRIANGLE_STRIP

Sıralı noktalardan(3 ve daha fazla olabilir) üçgenler oluşturmak için,yani n1(1.nokta diyelin),n2,n3,n4,n5,n6 ....nn olsun.n1,n2,n3 bir üçgen olacak,n2,n3,n4 bir üçgen olacak,n3,n4,n5 bir üçgen ve nn'e kadar sürecek.

GL_QUAD_STRIP

GL_TRIANGLE_STRIP'tin dörtgen versiyonu denilebilir.Son iki onktayı,sonraki iki nokta ile birleştirip dörtgen oluşturur.n1,n2,n3,n4 bir dörtgen,n3,n4,n5,n6 diğeri.

GL_TRIANGLE_FAN

(n1,n2,n3,n4,n5,n6):n1,n2,n3 bir üçgen,n5,n1,n4 bir diğeri,n5,n4,n3 diğeri.Şekil yelpaze gibi olur.

glEnd();

Çizim durumunu bitir demek.Bu sayede glBegin'de belirttiğimiz çizim modunu bitirip,başka bir çizim moduna geçebiliriz.
Renk nasıl verilir?Nokta nasıl belirlenir?

glColor3f(1,0,0);

glColor3f ile renk belirleriz.glColor3f(kırmızı,yeşil,mavi) şeklindedir.

Parametreler float cinsinden ve 0-1 arası değerler alır.glColor3d,double parametreleri alabilmek içindir.

glVertex2f(0,0);

glVertex2f(float x,float y) şeklinde kullanılır ve bu fonksiyon noktaların kordinatlarını gösterir.glVertex3d double parametreleri kullanabilmek ve noktanın kordinat düzlemindeki hassasiyetini artırmak için kullanılır.

*Gelecek yazımızda 3 boyutlulara geçmeden önce "daire nasıl çizilir?" konusuna bakacağız:hey
 

hewara

Üyecik
merhaba,
devc++ compiler kullanıyorum... 3 boyutlu küre çizmeye calıştım ama hata raporu verdi (opengl redbooktaki aynı örneği yazdım). Ayrıca başka bi kitaptan bir kübün bütün yüzlerini tanımlayarak küb çizmeye çalıştım ama gorebildigim 2 boyutlu bir kare oldu!!!
nerde hata yapıyorum? neyi eksik yapıyorum çözemedim??
yardımcı olursanız sevinirim...
saygılar,
 

merakettim

Homo Sapiens Sapiens
Özel üye
Hocam bunun çeşitli sebepleri olabilir.Eğer kamera (gluLookAt) kullanmıyorsan ilk bakışda sadece ön yüz görünecektir.Bu sorunu "glRotatef(float açı,float x,float y,float z)"kullanarak,verilen açı kadar işaretlediğin kordinat etrafnda kıvrılmasını sağlayarak giderebilirsin.Eğer derinlik tamponu kullanmıyorsa zaten çizimin 2 boyutlu sayılır.Derinlik tamponu kullanmalısın.Derinlik tamponu kullanmak için ise "glutInitDisplayMode'un" argümanlarına ek olarak "|" operatörü ile "GLUT_DEPTH" sabitini eklemeli ve derinlik testi yapmalısın.Derinlik testini ise "glEnable" fonksiyonuna "GL_DEPTH_TEST" sabitini argüman olarak atayarak kullanmalısın."glEnable(GL_DEPTH_TEST)".

Ayrıca ekran temizlenirken,"derinliği de temizlesin" diye "glClear'a" "|" operatörü ile "GL_DEPTH_BUFFER_BIT" sabitini eklemek gerek.Sorun çözülecektir.;)
 

hewara

Üyecik
teşekkür ederim yardımların için... solediklerinin hepsini yaptım.. şu an elimde sürekli donen bir kure var!

takıldıgım nokat su! rotate komutunu kaldırdıgım zaman ekranda sadece 2 boyutlu bir kare goruyorum... ben cismin donecegeni hesaba katmamıştım, elle bir kagıt uzerine kup cizersin ya işte ole bir şey bekliyodum...

benim projemde yapmam gereken şey bu kurenin vertex normallerini bulup, bu vertexlere bir illumination model uygulamak. daha sonrada linearly interpolate etmek(ki bu kısmını nasıl yapacagımı bilmiyorum). buna gouraud rendering deniyor...


yüzey normallerini bulup buradan vertex normallerini asıl bulacagımı biliyorum... ama buldugum bu vertex normallerini ve tanımlayacagım linearly interpolate olayını programda nereye koyacagımı bilmiyorum??
karışık oldu biraz (!) umarım anlatabildim...

saygılar,
 

merakettim

Homo Sapiens Sapiens
Özel üye
Hocam nesnenin sürekli dönmesinin sebebe tahminimce şöyledir.

float aci;
aci++;
glRotatef(aci,0,0,1);


Eğer bu şekilde kullanıyorsanız her döngüde aci değişkeni artacaktır ve sürekli dönecektir.Eğer aci değişkeni sabit olursa sürekli dönmez,sadece belirlenen açı kadar,belirlenen eksende ötelenir.

glRotatef(60,0,0,1);


Diğer soruna bakacak olursak,senin anlatmak istediği sanırım ön yüz büyük,arka taraflar,derinleştikçe küçük görünsün?
Bunu yapmak için boşuna uğraşma.Kamera kullanırsan sorun hallolur.
 

hewara

Üyecik
merhaba,
yok ön yüz büyük arka yüz küçük degil sorum!

vertex normallerini bulduktan sonra bu vertexlere bi illumination model uyguluyorum(diffuse, ambient,specular...).

dolayısıyla vertexlerde bu modeller gecerli ve cismin orta noktasındaki ya da daha genel bi tanımla herhangi bi noktasındaki(vertexler dahil degil çünkğ vertexlerdeki intensityi biliyoruz) intensity bulmak için bir intepolation uygulamam gerekiyor.

GLfloat InterpolatedValue(GLfloat KFinitvalue, GLfloat KFfinalvalue, int N, int f)
{
GLfloat ivalue;
ivalue=KFfinalvalue+f*(KFfinalvalue-KFinitvalue)/N-1;
}

vertexlerdeki intensity ben tanımlıyorum diger noktalardaki intensity de yukardaki formulu kullanarak bulmalıyım sanırım!!?

bu arada ilgilendigin için ne kadar teşekkür etsem azdır...
saygılar,
 
Top