OpenGL Quadrics
(3602 kelime) (716 okuma)
//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
|