| |  
 OpenGL Quadrics
 //Evet uzun bir aradan sonra
tekrar bir döküman.
 //Bu uzun aranın nedeninin benim
tembelliğimle uzaktan yakından alakası yok.:D
 //Tek sebebi okul.Ama bu gece
biraz zaman ayırdım ve hallettim bu dökümanı.
 //Sitedeki dökümanlar arasında
biraz dolandım ve OpenGL Quadricleri ile ilgili
 //birşey olmadığını gördüm.Bu
dökümanda quadriclerin ne olduğunu ve nasıl
 //kullanıldığını öğrenicez.
 //İlk olarak nedir bu quadricler??
 //OpenGL ile kendi çizimlerimizi
yapabiliriz.Bunu çizgilerle üçgenlerle vs yapıyoruz.
 //Ama OGL içinde hazır gelen bazı
objeleride kullabiliriz.Bunlar OpenGL Utility Library içinde.
 //Bu
objeler;diskler,silindirler,koniler ve küreler.İşte bunlara quadricler
deniyor.
 
 //Nasıl kullanırız??
 //Programımızda quadricleri
kullanmak için önce bir tane yaratmamız lazım.Çiziceğimiz şekil
 //ne olursa olsun önce bir tane
quadric object tanımlamamız lazım.
 // GLUquadricObj *pQuadObj;
 //şeklinde yapılabilir.
 //Sonra gluNewQuadric();
fonksiyonu ile bunu yaratıyoruz.
 //Bundan sonra çizilicek olan
şeklin özelliklerini ayarlamak için bazı fonksiyonlarımız var.
 //bunlar:
 
 //1-gluQuadricDrawStyle(GLUquadricObj
*pObj,GLenum style);
 //  Bu arkadaşımız çizilicek
şeklin nasıl çiziliceğini belirtiyor.İlk parametre
 //tanımladığımız quadric
obje(pQuadObj),style parametresine şunlar gelebilir
 //GLU_FILL(içi
dolu),GLU_LINE(çizgi),GLU_POINT(noktalar),GLU_SILHOUTTE(siluet) yanlış
yazdık kesin
 //neyse :D
 
 //2-gluQuadricNormals(GLUquadricObj
*pObj,GLenum normal);
 //  Bu fonksiyon ile
çiziceğimiz obje için normallerin nasıl yaratılacağını ya da
 //yaratılmayacağını
belirtiyoruz.normal parametresi GLU_NONE olursa normaller
yaratılmaz.Yani objemiz
 //ışıktan etkilenmez.GLU_FLAT
olursa her yüzey için bir normal oluşturulur bu bize flat shading verir.
 //her yüzey tek tonda aydınlanır
pek güzel bi görüntü diil bugün için :D.
 //ve son olarak GLU_SMOOTH bununla
objenin her noktası için bir normal yaratılır ve güzel bir
 //aydınlanma elde ederiz.
 
 //3-gluQuadricOrientation(GLUquadricObj
*pObj,GLenum orientation);
 // bu fonksiyon yaratılan
normallerin içe mi dışa mı dönük olduğunu ayarlıyor.
 //orientation parametresi
GLU_OUTSIDE olursa normaller dışa bakıyor.GLU_INSIDE olursa
 //içe bakıyor.Normaller dışa
bakarsa objenin dışı aydınlanır içe bakarsa içi.
 
 //4-gluQuadricTexture(GLUquadricObj
*pObj,GLenum texCoords);
 // bu fonksiyon ile objemiz için
texture koordinatlarının yaratılıp yaratılmayacağını belirliyoruz.
 //eğer objemize texture
uygulayacaksak texCoords GL_TRUE uygulamayacaksak GL_FALSE olur.
 
 //evet bunlar objelerimizin
özelliklerini belirliyor.
 //son olarak objeler ile çizim
işimiz bitince hafızadan silmek için
 // gluDeleteQuadric(GLUquadricObj
*pObj); fonksiyonunu kullanıyoruz ve ortalığı temizliyoruz :]
 
 //Evet şimdi programa gelelim bu
kadar gevezelik yeter :)
 //Win32 API kullanarak OpenGL
Programlamaya giriş dökümanı üstüne ekliyorum bu programı
 //o dökümanın açıklamalarını
çıkarıyorum.
 //eski döküman burda:  http://www.oyunyapimi.org/modules.php?name=Sections&op=viewarticle&artid=23
 //
 
 #define
WIN32_LEAN_AND_MEAN
 
 #define SCREEN_WIDTH 800
 #define SCREEN_HEIGHT 600
 #define SCREEN_DEPTH 32
 
 #include <windows.h>
 #include
<math.h>        //sin ve cos fonksiyonlarını kullacağız.
 #include
<stdlib.h>     //free komutu için
 #include <glgl.h>
 #include <glglu.h>
 #include
<glglaux.h>    //texture
yukleme için
 
 #pragma
comment(lib,"opengl32.lib")
 #pragma comment(lib,"glu32.lib")
 #pragma comment(lib,"glaux.lib")
 
 HDC g_hdc;
 HGLRC g_hrc;
 float aci=0.0f;
 
 LRESULT CALLBACK WndProc (HWND
hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam);
 
 int WINAPI WinMain(HINSTANCE
hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nShowCmd)
 {
 WNDCLASSEX
winclass;
 HWND hwnd;
 MSG msg;
 GLUquadricObj
*pQuadObj=0;    //Kullanacağımız
quadric obje!
 float
lightPos[4]={-50.0f,0.0f,20.0f,0.0f};  //ışığın yeri
 UINT 
textureID;          
           
      //texture
için
 bool bBitti;
 
 winclass.cbSize=sizeof(WNDCLASSEX);
 winclass.style=CS_HREDRAW|CS_VREDRAW;
 
 winclass.lpfnWndProc=WndProc;
 winclass.cbClsExtra=0;
 winclass.cbWndExtra=0;
 winclass.hInstance=hInstance;
 
 winclass.hIcon=LoadIcon(NULL,IDI_APPLICATION);
 winclass.hCursor=LoadCursor(NULL,IDC_ARROW);
 winclass.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);
 winclass.lpszMenuName=NULL;
 winclass.lpszClassName="patlican";
 winclass.hIconSm=LoadIcon(NULL,IDI_WINLOGO);
 
 
 
 if(RegisterClassEx(&winclass)==NULL)
 return 0;
 
 hwnd =
CreateWindowEx(NULL,
 "patlican",
 "Quadricler ile Dünya",
 WS_OVERLAPPEDWINDOW,
 100,100,
 SCREEN_WIDTH,SCREEN_HEIGHT,
 NULL,
 NULL,
 hInstance,
 NULL);
 
 if(hwnd==NULL)
 return 0;
 
 
 PIXELFORMATDESCRIPTOR pfd;
 
 pfd.nSize =
sizeof(PIXELFORMATDESCRIPTOR);
 pfd.nVersion
= 1;
 pfd.dwFlags =
PFD_DRAW_TO_WINDOW
 |
PFD_SUPPORT_OPENGL
 |
PFD_DOUBLEBUFFER;
 pfd.dwLayerMask = PFD_MAIN_PLANE;
 pfd.iPixelType = PFD_TYPE_RGBA;
 
 pfd.cColorBits = SCREEN_DEPTH;
 pfd.cDepthBits = 16;
 pfd.cAccumBits = 0;
 pfd.cStencilBits = 0;
 
 g_hdc=GetDC(hwnd);
 
 
 int
nPixelFormat;
 if
((nPixelFormat=ChoosePixelFormat(g_hdc,&pfd))==FALSE )
 {
 MessageBox(NULL, "Pixel Format seçme başarısız!", "Hata", MB_OK);
 PostQuitMessage(0);
 }
 
 if
(SetPixelFormat(g_hdc, nPixelFormat, &pfd) == FALSE)
 {
 MessageBox(NULL, "SetPixelFormat başarısız!", "Hata", MB_OK);
 PostQuitMessage(0);
 
 }
 
 
 g_hrc=wglCreateContext(g_hdc);
 wglMakeCurrent(g_hdc,g_hrc);
 
 //quadric
objemizi yaratıyoruz.
 //eğer
yaratmazsak program çakılır. :D
 pQuadObj =
gluNewQuadric();
 ///Burda
quadric obje ile ilgili bir kaç ayar yapıcaz en başta anlattığım
fonksiyonları kullanarak.
 //objemizi içi
dolu çizicez.
 gluQuadricDrawStyle(pQuadObj,GLU_FILL);
 //her nokta
için bir normal istiyoruz.
 gluQuadricNormals(pQuadObj,GLU_SMOOTH);
 //normaller
dışarı bakıyor.
 gluQuadricOrientation(pQuadObj,GLU_OUTSIDE);
 //texture
kordinatlarının yaratılmasını istiyoruz.
 gluQuadricTexture(pQuadObj,GL_TRUE);
 
 
 //diğer OpenGL
ayarları
 glEnable(GL_CULL_FACE);    //arka yüzleri çizmek istemiyoruz.
 glEnable(GL_LIGHTING);    //ışıklandırmayı açıyoruz.
 glEnable(GL_LIGHT0);    //0 numaralı ışığı aktif hale
getiriyoruz.
 glEnable(GL_TEXTURE_2D);//textureleri
aktif hale getiriyoruz.
 //bu fonksiyon
ile ışığın yerini değiştirebiliyoruz.
 glLightfv(GL_LIGHT0,GL_POSITION,lightPos);
 
 //texture
yükleme.
 //buraları
açıklamıyorum fazla uzamasın diye.
 //burda sadece
harddiskten world.bmp adlı dosyayı yüklüyoruz ve texture olarak
hazırlıyoruz.
 AUX_RGBImageRec *pBitmap = NULL;
 pBitmap =
auxDIBImageLoad("world.bmp");
 
 if(pBitmap ==
NULL)
 return 0;
 glGenTextures(1, &textureID);
 glBindTexture(GL_TEXTURE_2D, textureID);
 gluBuild2DMipmaps(GL_TEXTURE_2D, 3, pBitmap->sizeX,
pBitmap->sizeY, GL_RGB, GL_UNSIGNED_BYTE, pBitmap->data);
 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
 
 if
(pBitmap)
 {
 if (pBitmap->data)
 free(pBitmap->data);
 free(pBitmap);
 }
 
 ShowWindow(hwnd,SW_MAXIMIZE);
 //SW_MAXIMIZE
pencereyi tam ekran yapıyor.
 UpdateWindow(hwnd);
 
 bBitti=false;
 
 while(bBitti==false)
 {
 if(PeekMessage(&msg, NULL, NULL, NULL, PM_REMOVE))
 {
 if (msg.message == WM_QUIT)
 bBitti = true;
 TranslateMessage(&msg);
 DispatchMessage(&msg);
 }
 
 
 glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
 glLoadIdentity();
 
 
 glTranslatef(0.0f,-10.0f,-200.0f);
 
 glRotatef(aci,0.0f,1.0f,0.0f);
 glRotatef(-90.0f,1.0f,0.0f,0.0f);//dünyanın düz görünmesi için 90 derece
döndürmek gerekiyor
 
 
 aci+=0.2f;
 if(aci>=360.0f) aci=0.0f;
 
 //yüklediğimiz texture i
seçiyoruz.
 glBindTexture(GL_TEXTURE_2D,textureID);
 ///bir küre çiziyoruz.
 //parametreler sırasıyla.
 //quadric objemiz.
 //yarıçap
 //boyuna kesitler
 //enine kesitler
 gluSphere(pQuadObj,50.0f,100,100);
 
 
 SwapBuffers(g_hdc);
 
 
 }
 //program
bitmeden quadric objemizi siliyoruz.
 gluDeleteQuadric(pQuadObj);
 DestroyWindow(hwnd);
 UnregisterClass("patlican",hInstance);
 return
msg.wParam;
 }
 LRESULT CALLBACK WndProc (HWND
hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
 {
 int 
height,width;
 switch(iMsg)
 {
 case
WM_CREATE:
 break;
 case WM_SIZE:
 width = LOWORD(lParam);
 height = HIWORD(lParam);
 
 if (height==0)
 {
 height=1;
 }
 glViewport(0,0,width,height);
 glMatrixMode(GL_PROJECTION);
 glLoadIdentity();
 gluPerspective(45.0f,(GLfloat)width/(GLfloat)height, 1 ,1000.0f);
 glMatrixMode(GL_MODELVIEW);
 glLoadIdentity();
 break;
 case WM_DESTROY:
 wglMakeCurrent(NULL,NULL);
 wglDeleteContext(g_hrc);
 PostQuitMessage(0);
 return 0;
 }
 return
DefWindowProc(hwnd, iMsg, wParam, lParam);
 }
 
 ////Notlar:
 // Bu program Microsoft Visual C++
6.0 ile yazılmıştır.
 // Programın çalışması için opengl
kütüphanelerinin bilgisayarınızda bulunması gerekli
 // ayrıca yeni bir proje
yaratırken win32 application seçmelisiniz.
 //
 // Bu programda anlatmadığım bazı
kısımlar var texture yükleme olayı mesela.Dökümanın amacı
 //quadricleri anlatmaktı bu yüzden
o kısımları geçtim.Sadece sonucun guzel gözükmesi için texture
 //ve ışıklandırma koydum.o
kısımları anlamıyorsanız önemli diil.
 //Quadriclerden sadece küreyi
çizdik diğerleri neler peki??Onları nasıl çiziyoruz tamam panik yok :]
 //Diğer quadricler için
fonksiyonlar şunlar.
 
 // Silindirler için:
 // void gluCylinder(GLUquadricObj
*qobj,GLdouble baseRadius,GLdouble topRadius,GLdouble height,GLint
slices,GLint stacks);
 // baseRadius taban
yarçapı,topRadius tavan yarıçapı,height boy,slices boyuna
kesitler,stacks enine kesitler,
 
 // Diskler için :
 // void gluDisk(GLUquadricObj *
qobj,GLdouble innerRadius,GLdouble outerRadius,GLint slices,GLint loops);
 // innerRadius iç çap,outerRadius
dış çap,slices kesitler,loops halkalar,
 
 // Belli bi miktar disk için :)))
 // void
gluPartialDisk(GLUquadricObj * qobj,GLdouble innerRadius,GLdouble
outerRadius,GLint slices,GLint loops,GLdouble startAngle,GLdouble
sweepAngle);
 // bundaki fark diskin hangi
açıdan başlıcağını ve nekadarlık bir açı çiziceğini
belirtebilmeniz.startAngle başlama açısı sweepAngle da miktarı.
 
 // Evet şimdi son birkaç not daha
ve tamamız.Diyelim ki koni yapmak istediniz.O zaman tepesinin yarıçapı
sıfır olan bir silindir
 // yapıyorsunuz ve koniniz oluyor.
:] yada altını sıfır yaparsınız ters koniniz olur.
 // Başka bir konu slice,stack ler
ile ilgili.Bu değerler çizdiğiniz objenin kalitesini belirliyor eğer
azaltırsanız obje daha az
 // polygon ile çiziliyor ve
kalitesi düşüyor bu kalite farkı ışıklandırmada da kendini belli ediyor
o yüzden çok düşük değerler
 // kullanmanızı tavsiye etmiyorum.
 
 // Evet geldik bir dökümanın daha
sonuna.Eğer anlaşılmayan bir şeyler varsa.
 // 1) Forumda sorabilirsiniz.
 // 2) Irc kanalında
sorabilirsiniz.(irc.enterthegame.com #oyunyapimi)
 // 3) Bana mail
atabilirsiniz(busakli@shadowytree.com)
 // 4) Kendiniz halletmeye
çalışabilirsiniz.
 //
 // Benden bu kadar :]
 
 
  Bu döküman ile
ilgili örnek VC++ 6 proje dosyalarını indirmek için tıklayın. 
 Barış S. Uşaklı (Black_Knight) :: 10/11/2003 :: www.oyunyapimi.org
 
 | 
 |