Bu site emekli olmuştur. Arşiv amaçlı olarak BT AKADEMİ sponsorluğunda yayın hayatına devam etmektedir.




C#nedir?com
 
YAZAR HAKKINDA
Çiğdem Çavdaroğlu
Çiğdem Çavdaroğlu
http://www.csharpnedir.com/
İletişme geçmek için tıklayın.
28 Makalesi yayınlanmakta.
Yazar hakkında detaylı bilgi için tıklayın.
Yayınlanan diğer makaleleri için tıklayın.
İlgili etiketler: (wparam basilmasi degeri eksenleri etrafinda filled glfloat isimli islemi klavyeden opengl parametre sembolik tuslarina tusuna C / Sys Prog. Çiğdem Çavdaroğlu
 
YAZI HAKKINDA
Türü : Makale
Serbest Köşede C#nedir?com üyelerinin hazırladıkları yazılar yayınlanır. Bu yazılar editör incelemesine girmeden yayınlanır.
Seviyesi : İleri
Kategori : C / Sys Prog.
Yayınlanma Tarihi : 17.6.2006
Okunma Sayısı : 41506
Yorum Sayısı : 1     yorum yaz
Site İçi AramaSİTE İÇİ ARAMA
Üye Girişini AçÜye GİRİŞİ
Üye girişi için tıklayın.
Kullanıcı Adı
Şifre
 
Beni her zaman hatırla
Bir hafta boyunca kullanıcı bilgilerinizi kullanıcı çıkışı yapana kadar hatırlar. (Paylaşılan bilgisayarlarda önerilmez.)
 
Şifremi / Kullanıcı Adımı unuttum.
 
.net TV RSS Serbest KÖŞE (?)
Serbest Köşede C#nedir?com üyelerinin hazırladıkları yazılar yayınlanır. Bu yazılar editör incelemesine girmeden yayınlanır.
emre TAŞ
Silindi
emre TAŞ
yazının devamı >
emre TAŞ
silindi
emre TAŞ
yazının devamı >
emre TAŞ
silindi
emre TAŞ
yazının devamı >
emre TAŞ
silindi
emre TAŞ
yazının devamı >
emre TAŞ
silindi
emre TAŞ
yazının devamı >
Makale Gönder Bende Yazmak İstiyorum
.net TV RSSBlogroll
Turhal Temizer
Conda install environment.yml Package 28.3.2024
Turhal Temizer
Mac OS/X Removing CUDA 28.3.2024
Burak Selim Şenyurt
Kurumsal Yazılımcının Oyun Geliştirme ile İmtihanı 28.3.2024
Burak Selim Şenyurt
Matematik ve Oyun Programlama - Missile Command - Final 28.3.2024
  Diğer Herşey
Sponsorlar
BT Akademi
Medya Portakal
Video Hosting Sponsoru
Csharpnedir.com bir Ineta üyesidir
Uzman Abi
Her Yönüyle C# - Sefer Algan
C ve OpenGL : Döndürme ve Öteleme İşlemleri
 
Kapat
Sayfayı Yazdır Sık Kullanılanlara Ekle Arkadaşıma Gönder MySpace Del.Ico.Us Digg Facebook Google Mixx Reddit StumbleUpon
Bu yazımızda üç boyutlu çizimler üzerinde döndürme, öteleme, yakınlaşma ve uzaklaşma işlemlerinin nasıl yapılacağını ele alacağız. OpenGL ve C başlığı altında yürüttüğümüz yazı dizisinde, bir OpenGL penceresinin nasıl oluşturulduğunu, iki boyutlu ve üç boyutlu çizimlerin nasıl yapıldığını ele almıştık ve OpenGL’in bu işlemleri yapan fonksiyonlarını incelemiştik. OpenGL kütüphanesi x, y ve z eksenleri etrafında döndürme, x, y ve z eksenleri boyunca öteleme işlemlerini yapan fonksiyonlar da içermektedir. Daha önce yaptığımız uygulamalarda kısmen kullandığımız bu fonksiyonları bu yazımızda ayrıntılarıyla ele alacağız.

void glTranslated(GLdouble x, GLdouble y, GLdouble z);
void glTranslatef(GLfloat x, GLfloat y, GLfloat z);

Geçerli görüntü matrisini, parametre olarak verilen öteleme matrisi ile çarparak görüntü matrisini değiştirir. Başka bir deyişle görüntüyü x, y ve z eksenleri boyunca öteler. Fonksiyonların x, y ve z parametreleri öteleme matrisinin değerleridir. glBegin ve glEnd fonksiyonları arasında çağrılırsa GL_INVALID_OPERATION hata kodunu üretir.
void glRotated(GLdouble angle, GLdouble x, GLdouble y, GLdouble z);
void glRotatef(GLfloat angle, GLfloat x, GLfloat y, GLfloat z);
Geçerli görüntü matrisini, parametre olarak verilen dönüşüm matrisi ile çarparak görüntü matrisini değiştirir. Başka bir deyişle görüntüyü x, y ve z eksenleri etrafında saat yönünde döndürür. Fonksiyonların x, y ve z parametreleri dönüşüm matrisinin değerleridir, angle parametresi ise belirtilen eksen etrafındaki döndürme açısının derece cinsinden değeridir. glBegin ve glEnd fonksiyonları arasında çağrılırsa GL_INVALID_OPERATION hata kodunu üretir.
Bu yazımızda, kullanıcının klavyeden gireceği karakterlere göre çizimi belli bir eksen etrafında döndüren, belli eksenler boyunca öteleyen bir uygulama oluşturacağız. Uygulama çalıştırıldığında başlangıçta hiçbir işlem yapılmayacak. Kullanıcı klavyeden belli karakterleri girdiğinde, uygulama girilen bu karakterlere göre işlem yapacaktır. Uygulamanın içeriğini özetleyecek olursak :
    - x , y ve z eksenleri boyunca öteleme işlemleri
    - x , y ve z eksenleri etrafında döndürme işlemleri

Daha önce yaptığımız uygulamalarda bir OpenGL çizim penceresi oluşturmuştuk. Bu pencere üzerinde iki ve üç boyutlu çizimler yapmıştık. Bu uygulamamızda yine aynı pencereyi kullanacağız ve üç boyutlu çizim yapacağız. Döndürme ve öteleme işlemlerinde kullanmak üzere global alanda aşağıdaki değişkenleri tanımlayalım :

BOOL filled = FALSE;
BOOL rotate = FALSE;
GLfloat rotateAngle = 0.0f;
GLfloat xRotate = 0.0f, yRotate = 0.0f, zRotate = 0.0f;
GLfloat xTranslate = 0.0f, yTranslate = 0.0f, zTranslate = -7.0f;
Bu değişkenleri ne amaçla kullanacağımıza kısaca değinelim. Uygulamamızda bir küp oluşturacağız. OpenGL kütüphanesi bu kübü, sadece kenar çizgileri ile gösterebilmemize ya da yüzeylerini boyayarak gösterebilmemize izin verir. filled isimli değişkeni de bu durumu belirlemek için kullanacağız. Uygulamanın çalışma zamanında, kullanıcı klavyeden ’f’ (fill) tuşuna basarak bu seçeneği değiştirebilecek. Kullanıcı klavyeden ’t’ (turn) tuşuna bastığında şekil döndürülecek, tekrar ’t’ tuşuna bastığında ise şekil o anki açısıyla sabit biçimde gösterilecek. rotateAngle isimli değişken, şeklin döndürülme açısını belirleyecek. xRotate, yRotate ve zRotate değişkenleri ise şeklin hangi eksenler etrafında döndürüleceğini belirleyecek. Döndürme işlemini başlatmak veya durdurmak için kullanıcı klavyeden ’t’ (turn) tuşuna basacak. Döndürme eksenlerini ayarlamak için ise eksen isimlerini ifade eden ’x’, ’y’ ve ’z’ tuşlarına basacak. xTranslate, yTranslate ve zTranslate değişkenleri, x, y ve z eksenleri boyunca yapılacak öteleme miktarını belirleyecek. Kullanıcı klavyeden ’l’ (left), ’r’ (right), ’u’ (up) ve ’d’ (down) tuşlarına bastıkça bu değişkenlerin değerlerini değiştireceğiz. Dolayısıyla öteleme matrisinin değerlerini değiştirmiş olacağız.

Uygulamamızda çizim işlemlerini yaptığımız fonksiyon ’DrawGLScene’ isimli fonksiyon idi. Uygulamanın çalışma zamanında herhangi bir mesaj alınmadığı sürece bu fonksiyon çağrılır ve ekrana çizim işlemi yapılır. DrawGLScreen fonksiyonunun hemen ardından SwapBuffers isimli fonksiyon çağılır ve görüntü tamponundaki değişiklikler ekrana yansıtılır. Bu uygulamada DrawGLScreen isimli fonksiyonun içeriğini değiştireceğiz. Ekrana önce yapılacak değişikliklerin daha iyi anlaşılması için x, y ve z eksenlerini belirten bir koordinat sistemi çizdireceğiz, ardından bir küp çizdireceğiz. Şimi DrawGLScreen fonksiyonumuzu inceleyelim :

int DrawGLScene(GLvoid)
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glLoadIdentity();     DrawCoordiateSystem();

    glLineWidth(1.0f);
    glTranslatef(xTranslate,yTranslate,zTranslate);
    glRotatef(rotateAngle,xRotate,yRotate,zRotate);

    if (filled)
       glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
    else
       glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);

    glBegin(GL_QUADS);
    glColor3f(0.0f,0.5f,0.1f);
    glVertex3f(1.0f,1.0f,-1.0f);
    glVertex3f(-1.0f,1.0f,-1.0f);
    glVertex3f(-1.0f,1.0f,1.0f);
    glVertex3f(1.0f,1.0f,1.0f);

    glColor3f(0.0f,0.4f,0.0f);
    glVertex3f(1.0f,-1.0f,1.0f);
    glVertex3f(-1.0f,-1.0f,1.0f);
    glVertex3f(-1.0f,-1.0f,-1.0f);
    glVertex3f(1.0f,-1.0f,-1.0f);

    glColor3f(0.0f,0.2f,0.7f);
    glVertex3f(1.0f,1.0f,1.0f);
    glVertex3f(-1.0f,1.0f,1.0f);
    glVertex3f(-1.0f,-1.0f,1.0f);
    glVertex3f(1.0f,-1.0f,1.0f);

    glColor3f(0.0f,0.0f,0.5f);
    glVertex3f(1.0f,-1.0f,-1.0f);
    glVertex3f(-1.0f,-1.0f,-1.0f);
    glVertex3f(-1.0f,1.0f,-1.0f);
    glVertex3f(1.0f,1.0f,-1.0f);

    glColor3f(0.8f,0.1f,0.2f);
    glVertex3f(-1.0f,1.0f,1.0f);
    glVertex3f(-1.0f,1.0f,-1.0f);
    glVertex3f(-1.0f,-1.0f,-1.0f);
    glVertex3f(-1.0f,-1.0f,1.0f);

    glColor3f(0.0f,0.8f,0.0f);
    glVertex3f(1.0f,1.0f,-1.0f);
    glVertex3f(1.0f,1.0f,1.0f);
    glVertex3f(1.0f,-1.0f,1.0f);
    glVertex3f(1.0f,-1.0f,-1.0f);

    glEnd();

    if (rotate == TRUE)
       rotateAngle += 0.25f;

    return TRUE;
}

Fonksiyonda glClear fonksiyonu ile görüntü tamponunu temizledikten sonra, koordinat sistemini çizen DrawCoordiateSystem isimli fonksiyonu çağırıyoruz. Bu fonksiyonun içeriği de şöyledir :

void DrawCoordiateSystem()
{
    glLineWidth(3.0f);
    //x ekseni
    glBegin(GL_LINES);
    glColor3f(1.0f,1.0f,1.0f);
    glVertex3f(-4.0f,-3.0f,-9.0f);
    glVertex3f(1.0f,-3.0f,-9.0f);
    glEnd();     //y ekseni
    glBegin(GL_LINES);
    glColor3f(1.0f,1.0f,1.0f);
    glVertex3f(-4.0f,-3.0f,-9.0f);
    glVertex3f(-4.0f,2.0f,-9.0f);
    glEnd();

    //z ekseni
    glBegin(GL_LINES);
    glColor3f(1.0f,1.0f,1.0f);
    glVertex3f(-4.0f,-3.0f,-9.0f);
    glVertex3f(-4.0f,-3.0f,-14.0f);
    glEnd();
}

DrawCoordiateSystem fonksiyonundan incelemeye başlayalım. Bu fonksiyonda x, y ve z eksenlerini ifade edecek üç çizgi çizdireceğiz. Eksenlerin diğer çizimlerden ayırd edilebilmesi için öncelikle çizgi kalınlığını değiştiriyoruz. OpenGL kütüphanesinin glLineWidth isimli API fonksiyonu çizgi kalınlığını değiştirir. Bu fonksiyonun prototip bildirimine bakalım :

void glLineWidth (
    GLfloat width //Çizgi kalınlığı
);
glLineWidth API fonksiyonu float türünde bir parametre alır. Bu parametre çizgi kalınlığını belirtir. Varsayılan çizgi kalınlığı 1.0’dır. Koordinat sisteminin eksenlerini çizmek için glLineWidth fonksiyonunu 3.0f parametresini geçerek çağırıyoruz ve çizgi kalınlığının 3.0 olmasını sağlıyoruz. Eksen çizgilerini çizmek için, çizimi GL_LINES sembolik sabiti ile başlatıp çizim rengini beyaz yapıyoruz. Ardından eksen çizgilerini glVertex3f fonksiyonunu kullanarak çiziyoruz.

Eksen çizgilerinin çizimini tamamladıktan sonra kübün çizimine geçiyoruz. Çizgi kalınlığını tekrar 1.0 yapmak için glLineWidth fonksiyonunu 1.0f parametresini geçerek çağırıyoruz. Şimdi döndürme ve öteleme işlemlerini yapacak olan fonksiyonları çağırabiliriz. Koordinat eksenlerinin bu işlemlerden etkilenmesini önlemek için eksen çizimlerini bu fonksiyonları çağırmadan önce yapıyoruz. Öteleme işlemi için glTranslatef, döndürme işlemi için ise glRotatef fonksiyonunu uygun parametre değişkenlerini geçerek çağırıyoruz. Bu fonksiyonlara geçilen parametre değişkenleri, global alanda tanımlamış olduğumuz değişkenlerdir. Bu değişkenlerin değerlerini uygulamanın çalışma zamanında kullanıcının klavyeden gireceği bilgilere göre güncelleyeceğiz. Böylece her çizim öncesi parametre değişkenlerinin değerleri, dolayısıyla döndürme ve öteleme matrislerinin değerleri değişmiş olacak.

Döndürme ve öteleme işlemlerinin ardından kübün çizimine geçmeden önce çizilecek poligonun çizim modunu belirlemek üzere glPolygonMode OpenGL API fonksiyonunu çağırıyoruz. Bu fonksiyonun prototip bildirimini hatırlayalım :

void glPolygonMode (
    GLenum face, //İşlemden etkilenecek olan yüzeyler
    GLenum mode //Çizim biçimi
);
glPolygonMode OpenGL API fonksiyonu, çizilecek kapalı alanın pikselleştirilme biçimini ayarlar. Fonksiyonun iki parametre değişkeni bulunmaktadır. İlk parametre değişkeni verilen özellikten etkilenecek olan yüzeyi veya yüzeyleri ifade eder. Bu parametre değişkeni yerine G_FRONT sembolik sabiti geçilirse sadece ön yüzeyler, GL_BACK sembolik sabiti geçilirse sadece arka yüzeyler, GL_FRONT_AND_BACK sembolik sabiti geçilirse hem ön hem de arka yüzeyler atanacak özellikten etkilenecektir. Fonksiyonun ikinci parametre değişkeni atanacak olan özelliği ifade eder. Bu parametre değişkeni yerine GL_POINT sembolik sabiti geçilirse çizilecek olan kapalı alan noktalarla gösterilir, GL_LINE sembolik sabiti geçilirse çizilecek olan kapalı alan alanın kenarlarından geçen çizgilerle gösterilir, GL_FILL sembolik sabiti geçilirse çizilecek olan kapalı alan yüzeyleri boyanarak gösterilir. DrawGLScene fonksiyonunda, eğer filled değişkeninin değeri TRUE ise çizim GL_FILL modunda, filled değişkeninin değeri FALSE ise çizim GL_LINE modunda yapılıyor. Kullanıcının klavyeden gireceği bilgilere göre filled değişkeninin değeri değiştirilerek uygulamanın çalışma zamanında çizim modunu değiştirmek mümkün olmaktadır.

Çizim modunu da ayarladıktan sonra küp yüzeylerinin çizimine geçiyoruz. Çizimi GL_QUADS modunda başlatarak küp yüzeylerini dört köşe koordinatlarının değerlerini geçerek çiziyoruz. Her yüzey için glColor3f API fonksiyonu ile başka renk atıyoruz. Bu sayede yaptığımız işlemi uygulamanın çalışma zamanında görebilmemiz kolaylaşacaktır. Küp yüzeylerinin çizimini tamamladıktan sonra eğer çizim döndürülmekte ise, dönme açısının değerini 0.25f kadar artırıyoruz. Her çizim sonrası bu değer artırılarak sürekli bir dönme işleminin yapılması sağlanmaktadır.

Çizim fonksiyonumuzdan sonra şimdi pencere fonksiyonumuzu inceleyelim. Pencere fonksiyonunda, gelen mesajları dinleyerek kullanıcının klavyeden gireceği bilgiler doğrultusunda, uygulamada kullandığımız global değişkenlerin değerlerini değiştireceğiz. Önce fonksiyonumuzu inceleyelim :

LRESULT CALLBACK WndProc (HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
{
    static HWND hWndChild;     switch (uMsg) {
       case WM_CLOSE :
          PostQuitMessage(0);
          return 0;

       case WM_SIZE :
          ReSizeGLScene(LOWORD(lParam),HIWORD(lParam));
          return 0;

       case WM_COMMAND :
          sbreak;

       case WM_CHAR :

          if (wParam == ’t’)
             rotate = rotate == TRUE ? FALSE : TRUE;

          else if (wParam == ’x’)
             xRotate = abs(xRotate - 1.0f);

          else if (wParam == ’y’)
             yRotate = abs(yRotate - 1.0f);

          else if (wParam == ’z’)
             zRotate = abs(zRotate - 1.0f);

          else if (wParam == ’f’)
             filled = filled == TRUE ? FALSE : TRUE;

          else if (wParam == ’r’)
             xTranslate += 0.25f;

          else if (wParam == ’l’)
             xTranslate -= 0.25f;

          else if (wParam == ’u’)
             yTranslate += 0.25f;

          else if (wParam == ’d’)
             yTranslate -= 0.25f;

          else if (wParam == ’i’)
             zTranslate += 0.25f;

          else if (wParam == ’o’)
             zTranslate -= 0.25f;

          break;
     }

     return DefWindowProc(hWnd,uMsg,wParam,lParam);
}

Kullanıcının klavyeden girdiği bilgiler, pencere fonksiyonuna WM_CHAR mesajı aracılığı ile iletilirler. Mesaj döngüsünün işlendiği switch-case ifadesinde, WM_CHAR mesajının alınması durumunda önceden belirlediğimiz bazı karakterlerin girildiğinin anlaşılması durumunda belli işlemlerin yapılmasını sağlıyoruz. Klavyeden ’t’ tuşuna basıldığında çizimin döndürülme durumunu ayarlıyoruz. Kullanıcı bir kere t tuşuna bastığında rotate isimli değişkenin değeri TRUE olur ve çizim döndürülür. Klavyeden tekrar t tuşuna basıldığında rotate isimli değişkenin değeri FALSE olur ve döndürme işlemi durdurulur. Klavyeden x, y veya z tuşlarına basılması durumunda xRotate , yRotate ve zRotate isimli değişkenlerin değerlerini değiştiriyoruz. Bu tuşlara ilk kez basılması durumunda değişkenlere 1.0 değeri atanır ve değeri 1.0 olan eksenler etrafında döndürme işlemi yapılır. Klavyeden tekrar x, y veya z tuşlarına basılması durumunda bu değişkenlerin değerleri 0.0 olur ve o eksen etrafındaki döndürme işlemi sonlandırılır.

Klavyeden ’f’ tuşuna basılması çizimin biçimini belirlemektedir. f tuşuna ilk kez basılması durumunda filled isimli değişkenin değeri TRUE olur ve çizilen kübün yüzeyleri boyanır. Klavyeden tekrar ’f’ tuşuna basıldığında ise filled değişkeninin değeri FALSE olur ve küp sadece kenarlarını sınırlayan çizgilerle gösterilir.

Klavyeden ’r’ ve ’l’ tuşlarına basılması çizimin x ekseni doğrultusundaki öteleme miktarını değiştirir. Bu tuşlarla çizim sola ya da sağa doğru kaydırılabilir. Klavyeden ’u’ veya ’d’ tuşlarına basılması çizimin y ekseni doğrultusundaki öteleme miktarını değiştirir. Bu tuşlarla çizim yukarıya veya aşağıya doğru kaydırılabilir. Klavyeden ’o’ veya ’i’ tuşlarına basılması çizimin z ekseni doğrultusundaki öteleme miktarını değiştirir. Bu tuşlarla çizime yaklaşılması veya çizimden uzaklaşılması sağlanır.

Uygulamanın çalışma zamanındaki görünümü şu şekillerde olacaktır :

   

  

Bu yazımızda OpenGL ile eksenler boyunca öteleme ve eksenler etrafında döndürme işlemlerinin nasıl yapıldığını ele aldık. Yapmış olduğumuz uygulamayı buradan indirebilirsiniz. Bir sonraki yazımızda görüşmek üzere, mutlu günler dilerim.

* Kaynaklar :
   - OpenGL Platform SDK Help Book


Makale:
C ve OpenGL : Döndürme ve Öteleme İşlemleri C ve Sistem Programlama Çiğdem Çavdaroğlu
  • Yazılan Yorumlar
  • Yorum Yaz
HAZ
18
2006
OpenGl in çok güzel bir grafik kütüphanesi oldugunu bir defa daha goruyoruz. 3D işlemler ve grafik tabanlı desktop uygulamaların vazgecilmez aracını bize güzel bir şekilde tanıttıgınız için teşekkürler.
Sayfalar : 1 
Yorum yazabilmek için üye girişi yapmalısınız. Üye girişi için tıklayın.
Üye değilseniz Üyel Ol linkine tıklayarak üyeliğinizi hemen başlatabilirisniz.
 
  • Bu Konuda Son 10
  • Eklenen Son 10
  • Bu Konuda Geçmiş 10
Bu Konuda Yazılmış Yazılmış 10 Makale Yükleniyor
Son Eklenen 10 Makale Yükleniyor
Bu Konuda Yazılmış Geçmiş Makaleler Yükleniyor