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




Bu haberin geldigi yer: oyunyapimi.org
http://www.oyunyapimi.org

Bu haber icin adres:
http://www.oyunyapimi.org/modules.php?name=Sections&op=viewarticle&artid=46