İçindekilerGirişİndex
YukarıİlkÖncekiSonraki YokSon
Geriİleri
Yazdır

OpenGL ve GLUT ile Animasyon ve 3D

Tabiki cogunuzun istedigi statik sekiller cizmek yerine hareket:)Bunun icin openGL ile animasyonun nasil yapildigi hakkinda fikir sahibi olabilmek icin onceki ornekteki karemize bir animasyon ekleyelim.Genellikle goruntu ve cizmis oldugunuz sekillerin hareket etmesini isteyeceksiniz.Bunun icin programalam bilenlerinizin tahmin edebilecegi gibi objenizin koordinatlarini surekli degistirecek bir songu hazirlayip RenderScene fonksiyonunu cagirabilirsiniz.Boylelikle sekliniz pencerenin icerisinde hareket edecek.

GLUT kutuphanesi animasyon sirasi olusturmak icin bir fonksiyon sunmaktadir.glutTimerFuncadi verilen bu fonksiyon fonksiyonun ismini alarak calistirmadan once belirli bir sure beklemektedir.Bu fonksionun prototipi asagidaki sekildedir.

void glutTimerFunc(unsigned int msaniye,void(* func)(int value),int value);

Bu fonksiyon func adi verilen fonksiyonu cagirmadan once GLUT a belirtilen milisaniye kadar beklemesini soylemektedir.Value(Deger) parametresine ise kullanici tanimli istediginiz degeri verebilirsiniz.Zamanlayici tarafindan cagrilan fonksiyon

void TimerFunction(int value);

seklinde olacaktir.Windows zamanlayicisinin aksine bu yordam bir kere calistirilir.Devamli bir animasyon icin zamanlayiciyi fonksiyonun icinde tekrar baslatmalisiniz.

Cift Tamponlama(Double Buffering)

Grafik programalam da en onemli terimlerden birisi de cift tamponlamadir.Buözellik cizim kodunuzu isletirken cizim isleminin ekran disinda bir tampona yapilmasidir.Boylelikle bir degistirme(swap) komutu ekrana aninda hafizadaki gountunuzu yansitir.Cift tamponlama iki neden hizmet eder.Birincisi kompleks cizimler olusturulmak icin zaman alirlar ve her cizim asamsini gormek istemeyebilirsiniz.Cift tamponlama sayesinde goruntuyu tamamladiktan sonra kullaniciya gosterebilirsiniz.Kullanici hicbir zaman yarim bir goruntu gormez sadece tum goruntu tamamlandiktan sonra onu bir butun olarak gorur.Cift tamponalamnin ikinci bir kullanimi animasyon icindir.Her goruntu karesi gorunmeyen tampona kaydedilerek hazir oldugunda hizli bir sekilde ekrandaki goruntu ile degistirilir.

glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);

komutu cift tamponlamayi aktif hale getirir.

RenderScene yordam tanimi icerisindeki

glutSwapBuffers(); 

ifadesi ise glFlush yerine gecerek hem islenecek cizim komutlarini akitir hemde cift tamponlama modunda isek goruntuleri yer degistirir.Bu fonksiyon SINGLE (tek tampon) modunda iken de glFlush yerine kullanilabilir.Isterseniz animasyonda cift tamponlama yerine tek tamponlama kullanarak farki gorebilirsiniz.Tek tamponalama da surekli bir kesinti soz konusu olacaktir.

Nihayet 3D

Simdiye kadarki orneklerimiz hep basit cizimlerden olusuyordu.Ve bunun cogunuz icin ilginc olmadigini biliyorum.Sekillere derinlik vermek icin duz nesnelerden uzak durmaliyiz.GLUT kutuphanesi icinde bir duzine kadar hazir 3D obje bulundurmaktadir.Bunlar bir kureden bir caydanliga kadar degisik nesnelerdir ve isin guzel yani bu nesneler tek bir komut cagrisi ile! ekrana yansitilabilmektedir.Fonksiyonlar glutSolidXXX veya glutWireXXX seklinde tanimlidir.(Burada XXX sekle ozgu bir isim yerine gecmektedir.XXX diye bir obje yoktur).Mesela

glutWireTeapot(1.0f);

bir caydanlik cizmektedir.Simdi size bunlari ekrana yansitabilecek program kodunu verecegim.Daha 3D ogrenmeye cok yol var ama en azindan elimizde 3D birseyler bulunsun.Calisan ekranin uzerine sag kilikleyerek istediginiz sekli secebilir ve ok tuslarina basiali tutup 3D olarak objeyi inceleyebilirsiniz.İyi seyirler.Kodlar su anki bilginiz icin size karisik gelecektir.Zaten aciklamalari daha sonra yapacagiz.Sadece aldiginiz temellerin programda nasil kullanildgina goz atin.Oyunlarda bundan pek farkli kodlanmamaktadir.

Göster Gizle Kopar Satır Gizle Satır Göster
#include <windows.h>
#include <gl/gl.h>
#include <gl/glu.h>
#include <gl/glut.h>



// Donme miktarlari
static GLfloat xRot = 0.0f;
static GLfloat yRot = 0.0f;


// Isik degerleri ve koordinatlari
GLfloat  ambientLight[] = { 0.3f, 0.3f, 0.3f, 1.0f };
GLfloat  diffuseLight[] = { 0.7f, 0.7f, 0.7f, 1.0f };
GLfloat  specular[] = { 1.0f, 1.0f, 1.0f, 1.0f};
GLfloat  specref[] =  { 1.0f, 1.0f, 1.0f, 1.0f };

static int iShape = 1;

///////////////////////////////////////////////////////////////////////////////
// Menu secimlerine gore falglari uygun konuma getir
void ProcessMenu(int value)
  {
    iShape = value;

  glutPostRedisplay();
  }


// Ekrani cizmek icin cagrilir
void RenderScene(void)
  {
  // Pencereyi temizle
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);


    // Matris durumunu kaydet ve donusu yap
  glPushMatrix();
  glRotatef(xRot, 1.0f, 0.0f, 0.0f);
  glRotatef(yRot, 0.0f, 1.0f, 0.0f);

    switch(iShape)
        {
        case 1:
            glutWireSphere(1.0f, 25, 25);
            break;

        case 2:
            glutWireCube(1.0f);
            break;

        case 3:
            glutWireCone(0.30f, 1.1f, 20, 20);
            break;

        case 4:
            glutWireTorus(0.3f, 1.0f, 10, 25);
            break;

        case 5:
            glutWireDodecahedron();
            break;

        case 6:
            glutWireOctahedron();
            break;

        case 7:
            glutWireTetrahedron();
            break;

        case 8:
            glutWireIcosahedron();
            break;

        case 9:
            glutWireTeapot(1.0f);
            break;

        case 11:
            glutSolidSphere(1.0f, 25, 25);
            break;

        case 12:
            glutSolidCube(1.0f);
            break;

        case 13:
            glutSolidCone(0.30, 1.1f, 20, 20);
            break;
    
        case 14:
            glutSolidTorus(0.3f, 1.0f, 10, 25);
            break;

        case 15:
            glutSolidDodecahedron();
            break;

        case 16:
            glutSolidOctahedron();
            break;

        case 17:
            glutSolidTetrahedron();
            break;

        case 18:
            glutSolidIcosahedron();
            break;

        default:
            glutSolidTeapot(1.0f);
            break;
        }


  // Transformasyonlari geri yukle
  glPopMatrix();

  // Cizim komutlarini akit
  glutSwapBuffers();
  }

// Bu fonksiyon cizim konteksti uzeirnde gereken baslatimlari yapar
void SetupRC()
  {
  // Siyah arak plan
  glClearColor(0.0f, 0.0f, 0.0f, 1.0f );

    // Derinlik testini ac
    glEnable(GL_DEPTH_TEST);

  // Isiklandirmayi ac
  glEnable(GL_LIGHTING);

  // Isig ayrala ve 0 da ac
  glLightfv(GL_LIGHT0,GL_AMBIENT,ambientLight);
  glLightfv(GL_LIGHT0,GL_DIFFUSE,diffuseLight);
  glLightfv(GL_LIGHT0,GL_SPECULAR,specular);
  glEnable(GL_LIGHT0);

  // Renk izlemeyi ac
  glEnable(GL_COLOR_MATERIAL);
  
  // materyal ozelliklerinin cizm rengine uyum saglamasini sagla
  glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);

  // Tum materyaller bir parlaklik ve yansimaya sahip olacaklar

  glMaterialfv(GL_FRONT, GL_SPECULAR,specref);
  glMateriali(GL_FRONT,GL_SHININESS,128);


  // Cizim rengini maviye ayarla
  glColor3ub(0, 0, 255);
  }

void SpecialKeys(int key, int x, int y)
  {
  if(key == GLUT_KEY_UP)
    xRot-= 5.0f;

  if(key == GLUT_KEY_DOWN)
    xRot += 5.0f;

  if(key == GLUT_KEY_LEFT)
    yRot -= 5.0f;

  if(key == GLUT_KEY_RIGHT)
    yRot += 5.0f;

  if(key > 356.0f)
    xRot = 0.0f;

  if(key < -1.0f)
    xRot = 355.0f;

  if(key > 356.0f)
    yRot = 0.0f;

  if(key < -1.0f)
    yRot = 355.0f;

  // Pencereyi yenile
  glutPostRedisplay();
  }


void ChangeSize(int w, int h)
  {
  GLfloat   lightPos[] = { -50.f, 50.0f, 100.0f, 1.0f };
  GLfloat nRange = 1.9f;

  // Sifirla bolunmeyi engelle
  if(h == 0)
    h = 1;

  // Viewportu pencere boyutlarina gore ayarla
    glViewport(0, 0, w, h);

  // Projeksiyon matris yiginini sifirla
  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();

  // Kesim hacmini elde et
    if (w <= h) 
    glOrtho (-nRange, nRange, -nRange*h/w, nRange*h/w, -nRange, nRange);
    else 
    glOrtho (-nRange*w/h, nRange*w/h, -nRange, nRange, -nRange, nRange);

  // Model goruntuleme matris yiginini sifirla
  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity();

  glLightfv(GL_LIGHT0,GL_POSITION,lightPos);
  }

int main(int argc, char* argv[])
  {
  int nSolidMenu;
  int nWireMenu;
  int nMainMenu;

  glutInit(&argc, argv);
  glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
  glutCreateWindow("GLUT Shapes");
  
  // Menu olustur
  nWireMenu = glutCreateMenu(ProcessMenu);
  glutAddMenuEntry("Kure",1);
  glutAddMenuEntry("Kup",2);
  glutAddMenuEntry("Koni",3);
  glutAddMenuEntry("Torus",4);
  glutAddMenuEntry("Dodecahedron",5);
  glutAddMenuEntry("Sekizgen",6);
  glutAddMenuEntry("Tetrahedron",7);
  glutAddMenuEntry("Icosahedron",8);
  glutAddMenuEntry("Caydanlik",9);


  nSolidMenu = glutCreateMenu(ProcessMenu);
  glutAddMenuEntry("Kure",11);
  glutAddMenuEntry("Kup",12);
  glutAddMenuEntry("Koni",13);
  glutAddMenuEntry("Torus",14);
  glutAddMenuEntry("Dodecahedron",15);
  glutAddMenuEntry("Sekizgen",16);
  glutAddMenuEntry("Tetrahedron",17);
  glutAddMenuEntry("Icosahedron",18);
  glutAddMenuEntry("Caydanlik",19);

  nMainMenu = glutCreateMenu(ProcessMenu);
  glutAddSubMenu("Tel", nWireMenu);
     glutAddSubMenu("Kati", nSolidMenu);
  glutAttachMenu(GLUT_RIGHT_BUTTON);
  
  glutReshapeFunc(ChangeSize);
  glutSpecialFunc(SpecialKeys);
  glutDisplayFunc(RenderScene);
  SetupRC();
  glutMainLoop();

  return 0;
  }

Dosya Listesi

İçindekilerGirişİndex
YukarıİlkÖncekiSonraki YokSon
Geriİleri
Yazdır