7- realtime programlamaya giriş = hareket ve dönüşümler
7- realtime programlamaya giriş = hareket ve dönüşümler
3d ortamda cizilen nesneleri, bazen baska yerlere tasimak, döndürmek yada ölçeğini değiştirmek isteriz.
3d ortamda yapabileceğimiz dönüşümler bellidir.
taşıma / moving / translation
döndürme / rotation
ölçekleme / scaling
opengl ile taşıma işlemini;
glTranslatef(x, y, z);
döndürme işlemini;
glRotatef(aci, x, y, z);
ölçek işlemini;
glScalef(x, y, z);
fonksiyon kalıpları ile yapabiliyoruz.
bunların nasıl çalıştığına bir bakalım
taşıma / glTranslatef(x, y, z);
glTranslatef fonksiyonunun üç değişkeni bulunur. bunlar nesnemizi uzayda götürmek istediğimi koordinatı belirtirler.
glTranslatef(10.0, 5.0, 0.0); fonkisyonunu çağırdığınız noktadan sonra gireceğiniz bütün çizim işlemleri, uzayın merkezi x yönünde 10, y yönünde 5 ve z yönnde 0 noktasına taşındıktan sonra yapılacaktır.
yani, biz aslında nesneleri taşıyamıyoruz. ancak, bir nesneyi çizerken, o nesneyi nerde çizmek istiyorsak, uzayın merkezini oraya götürebiliyoruz.
döndürme / glRotatef(aci, x, y, z);
buradaki fonksiyon biraz değişik.
öncelikle aci değeri, uzayı kaç derece döndürmek istiyorsak avrupa standartlarında derece cinsinden o değer.
diğer x, y, z ise; döndürme eksenini belirleyen değerler.
döndürme işlemi bilindiği üzere her zaman bir eksen üzerinde oluşur. eğer biz bir nesneyi döndürmek istiyorsak, onun dönme eksenini tanımlamalıyız.
dönme eksenini tanımlarken uzayda eksenin geçtiği iki nokta tanımlamamız gerekecektir. bu noktalardan birincisi uzayın merkezi, yani orjindir. ikincisi ise, bizim fonksiyonda tanımladığımız x,y,z noktasıdır.
ölçekleme/glScalef(x,y,z);
glScalef fonksiyonu uzayı, verdiğimiz ölçek kadar büyütüp küçültecektir. unutmayın ki, nesnenin kendi ölçeği 1.0´dır. yani 2.0 yaparsanız belirttiğiniz yönde nesne 2 katı genişler.
peki ben bir nesneyi merkezden 100 birim x yönünde ilerde çizmek istedim. bunun için glTranslatef(100.0, 0.0, 0.0); yaptım. ama o nesneyi çizdikten sonra çizdiğim bütün nesneler de 100 birim taşınmış oluyor. tekrar uzayın eski haline gelmesi için glTranslatef(-100.0,0.0,0.0); mı yapmalıyım.. peki bir döngü içinde rastgele şekilde bu dönüşümleri yaptırdıysak, nerden bilecez ki ne kadar ileri götürdüğümüzü? uzay karışacak :)...
elbette bunu önlemenin basit bir yolu var.
glPushMatrix(); bu fonksiyonu bir dönüşüm yapmadan önce kullanın. yukardaki örnekte, glTranslatef(100.0, 0.0, 0.0); yapmadan önce kullanın. sonra çiziminizi yapın. diğer nesnelerin uzayın asıl merkezine göre çizilmeye devam edebilmesi için, glPopMatrix(); yapın.
glPushMatrix, uzayın o anki koordinat sistemini, merkezini ve açısını hafızaya alır.
ardından glPopMatrix(); uyguladığımız yerde hafızadaki merkez açı ve ölçeği uzaya uygular.
örnek :
glTranslatef(15,0,0);
glBegin(GL_POLYGON);
glColor3f(1.0, 0.0, 0.0);
glVertex3f(-5.0,10.0,0.0);
glVertex3f(-5.0,0.0,0.0);
glVertex3f(5.0,0.0,0.0);
glVertex3f(5.0,10.0,0.0);
glEnd();
glBegin(GL_POLYGON);
glColor3f(1.0, 0.0, 0.0);
glVertex3f(-5.0,10.0,0.0);
glVertex3f(-5.0,0.0,0.0);
glVertex3f(5.0,0.0,0.0);
glVertex3f(5.0,10.0,0.0);
glEnd();
bu da dönüşümü hafızaya aldırarak uygulanmış hali
glPushMatrix();
glTranslatef(15,0,0);
glBegin(GL_POLYGON);
glColor3f(1.0, 0.0, 0.0);
glVertex3f(-5.0,10.0,0.0);
glVertex3f(-5.0,0.0,0.0);
glVertex3f(5.0,0.0,0.0);
glVertex3f(5.0,10.0,0.0);
glEnd();
glPopMatrix();
glBegin(GL_POLYGON);
glColor3f(1.0, 0.0, 0.0);
glVertex3f(-5.0,10.0,0.0);
glVertex3f(-5.0,0.0,0.0);
glVertex3f(5.0,0.0,0.0);
glVertex3f(5.0,10.0,0.0);
glEnd();
hayden hayırlı dönüşümler.