OpenGL'de Doku Kaplama
OpenGL'de Doku Kaplama
Kaplama.h
C/C++ kodu:
void KaplamaYarat(UINT kaplamalar[], int kaplamaNO ,char * strFileName);
OpenGL_Ders_3.h
C/C++ kodu:
#pragma once #include "resource.h" #include <windows.h> #include <stdlib.h> #include <math.h> // matematik fonksiyonları için başlık dosyası #include <glgl.h> // OpenGL32 kütüphanesi icin baslik dosyası #include <glglu.h> // GLU32 kütüphanesi icin baslik dosyası #include <vector> #define EkranGenis 800 // Pixel bazında ana pencerenin Genisligi #define EkranYuksek 600 // Pixel bazından ana pencerenin yüksekliği #define EkranDerinlik 16 // her pixel icin kullanacagımız bit sayısı #define OpenGL_GENISLIK 800 // OpenGL in kendi boyutundaki genişliği #define OpenGL_YUKSEKLIK 600 // OpenGL in kendi boyutundaki yüksekliği extern HINSTANCE hInst; extern HDC hdc; extern HWND hWnd; extern HGLRC hrc; extern TCHAR szWindowClass[100]; extern RECT winRect; extern int TamEkran; extern UINT Kaplamalar[4] ; // Render fonksiyonun prototipi void Render (); // init ve deinit icin kullanılacak fonksiyonların prototipleri void EkranModunuDegistir(); bool PixelFormatAyarla(HDC hdc) ; void OpenGLEkranAyarla(int gen, int yuk) ; void OpenGLINIT(int gen, int yuk) ; void OpenGLDEINIT();
Render.h
C/C++ kodu:
UINT Kaplamalar[4];
Init.cpp
C/C++ kodu:
/* burda Başlangıçta kullanılacak fonksiyonlar ve yapılar mevcut olacaktır.
NOT : Burdaki fonksiyonlar nadir olarak değişen fonksiyonlar olup bir çok
tutorial da aynı formatta olacaktır.Eğer değişim olacaksa bu sayfanın başında
değişiklik belli edilecektir. Init.cpp adındanda anlaşılacağı üzere initialize kısmıdır.
Opengl için tüm initialize lar burda yapılıyor ve dediğim nadir olarak değişecektir.
******** Tüm Derslerde bu format kullanılacaktır.
*/
#include "Opengl_ders_3.h"
// Ekran modunu, tam ekran seçilmiş ise değiştirmek için kullanılacak fonksiyon.
void EkranModunuDegistir()
{
DEVMODE dmSettings; // Device Mode degiskeni
memset(&dmSettings, 0, sizeof(dmSettings)); // Device Mode degiskenin hafizasını sıfırla
// Su an geçerli olan ekran ayarları bilgisini dmSettings yapısına doldur,sırala.
// ekran ayarlarından kasıt, ekran genişligi ,yüksekliği , monitor refresh rate vs.
if (!EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &dmSettings))
{
// Eger fonksiyon başarısız ise
MessageBox(NULL, "Ekran ayarları sıralanamadı", "Error", MB_OK);
return;
}
// Belirledigimiz pencerenin genişlik ve yükseligini dmSettings yapısına ata
dmSettings.dmPelsWidth = EkranGenis;
dmSettings.dmPelsHeight = EkranYuksek;
// Görüntü ayarlarını yeni atamış oldugumuz degerlerle birlikte degistir
int result = ChangeDisplaySettings(&dmSettings, CDS_FULLSCREEN);
if (result != DISP_CHANGE_SUCCESSFUL)
{
// Eger fonksiyon başarısız ise
MessageBox(NULL, "Display Mode Not Compatible", "Error", MB_OK);
PostQuitMessage(0);
}
}
// Pixel formatını ayarlamak icin kullanılacak fonksiyon, device context icin bir pixel format secmemiz gerekiyor
// önce pfd yapısını dolduruyoruz ve SetPixelFormat ile device contexte doldurdugumuz pixel formatı veriyoruz.
bool PixelFormatAyarla(HDC hdc)
{
PIXELFORMATDESCRIPTOR pfd = { 0 };
int pixelformat;
pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR);
pfd.nVersion = 1; // her zaman 1 olacak
pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER; // Opengl icin default ayarlar
pfd.dwLayerMask = PFD_MAIN_PLANE; // standart maskeleme icin, önemi yok
pfd.iPixelType = PFD_TYPE_RGBA; // pixellerimiz Red Green Blue ve Alpha kanallı olacak
pfd.cColorBits = EkranDerinlik; // Ekran derinligi,colorbits
pfd.cDepthBits = 0; // RGBA oldugunda derinlik biti gözardı edilir
pfd.cAccumBits = 0;
pfd.cStencilBits = 0;
// bizim belirrtiklerimze en uygun bi pixel format seç ChoosePixelFormat ile
if ((pixelformat = ChoosePixelFormat(hdc, &pfd)) == FALSE)
{
MessageBox(NULL, "ChoosePixelFormat basarisiz", "Error", MB_OK);
return FALSE;
}
// Yukarda uygun seçilen formatı hdc ile ilişkilendir
if (SetPixelFormat(hdc, pixelformat, &pfd) == FALSE)
{
MessageBox(NULL, "SetPixelFormat basarisiz", "Error", MB_OK);
return FALSE;
}
return TRUE;
}
// Opengl penceresinin boyutunun ayarlancagı fonksiyon
void OpenGLEkranAyarla(int gen, int yuk)
{
if (yuk == 0)
yuk = 1;
glViewport(0, 0, gen, yuk); //viewport u ayarla
glMatrixMode(GL_PROJECTION); //projection matriks i aktif matriks yap
glLoadIdentity(); //aktif matriks i identity yap yani resetle
glOrtho(0, gen, yuk, 0, 0, 1); //Clip olacak koordinatları belirle
glMatrixMode(GL_MODELVIEW); //modelview matriksi aktif matriks yap
glLoadIdentity(); //modelview matriks i resetle
}
void OpenGLINIT(int gen, int yuk)
{
hdc = GetDC(hWnd); // Device context kaynaklarda varsa al
// bu Handle to Device Context i yani hdc i programın canlı oldugu sürece bırakmıyoruz.
if (!PixelFormatAyarla(hdc)) //Pixel formatı ayarla
PostQuitMessage(0); //error varsa, çık
// Opengl için birde Rendering Context(hrc) gerekiyor , bunuda wglCreateContext ile yaratıyoruz.
hrc = wglCreateContext(hdc);
wglMakeCurrent(hdc, hrc); //Bu fonksyion ile su anki akif context i yarattigimiz hrc yap
OpenGLEkranAyarla(gen, yuk); //Opengl icin gerekli olan ekran ayarlarını yap, viewport ve glOrtho
}
// Opengl ile ilgili sistemden aldıgımız kaynakların geri verilmesi
void OpenGLDEINIT()
{
if (hrc)
{
wglMakeCurrent(NULL, NULL);
wglDeleteContext(hrc); // Opengl in rendering context i sisteme geri kazandır
}
if (hdc)
ReleaseDC(hWnd, hdc); // device context i sisteme geri kazandır
ShowCursor(TRUE); // Mouse un Cursor u göster (önceden gizli ise)
UnregisterClass(szWindowClass, hInst); // pencere classını bosalt
PostQuitMessage(0); // pencereye quit mesajı at
}
Kaplama.cpp
C/C++ kodu:
#include "Opengl_ders_3.h"
#include <glglaux.h>
/*
NOT : auxDIBImageLoad adlı fonksiyonu kullanabilmemiz için gerekli olan glaux.lib kütüphanesini
projeye eklememiz gerekiyor.
KaplamaYarat
------------
Bitmap i Kaplamaya çevirerek,Opengl renderda polygonları kaplayabilecegimiz kaplamaları yaratan fonksiyon
*/
void KaplamaYarat(UINT kaplamalar[], int kaplamaNO, char * strFileName)
{
if (!strFileName) // Eger dosya yolu boş ise hata ver
MessageBox(hWnd, "Kaplama Dosya Yolu Bozuk!", "HATA", NULL);
AUX_RGBImageRec *hBMP = NULL; // Projeye eklenmiş olan glaux.lib kütüphanesinden bir gösterge tanımlııoruz.
hBMP = auxDIBImageLoad(strFileName); // Bir fonksionla yolunu gosterdigimiz bitmap e bir gösterge elde ediyoruz
if (hBMP == NULL) // Eger dosyaya gösterge döndürmede basarısız olunduysa
MessageBox(hWnd, "Kaplama Hatalı işlendi,Kaplama gözükmicek", "HATA", NULL);
/*
Simdi elimizde kaplama bilgisi mevcut. Bunu opengl e koymamız gerekiyor.
Daha dogrusu generate texture işlemi yapmamız geerekiyor. glGenTextures fonksiyonu ile bunu
gerceklestiriyoruz. kaplamalar adlı dizide istedigimiz kaplamalar mevcut olacak, kaplamaNO
adlı degiskende o dizideki kaplamaların index i olacak. yani kaplamalar[kaplamaNO] bizim o an icin
ekledigimiz kaplamayı belirticek. Bundan kac tanede olacagını belirten degerde glGenTextures fonksionun
ilk aldıgı parametredir. Yani 1 tane bundan istiyoruz. ve KaplamaYarat adlı fonksiyon ilk cagrıldıgında
kaplamalar[0] bizim ilk atadıgımız kaplama olacak.
*/
glGenTextures(1, &kaplamalar[kaplamaNO]);
/*
Kaplamayı belirledikten sonra birde bu kaplamayı baglamamız gerekiyor.
Bunu glBindTexture fonksionu ile yapıyoruz. Ilk degeri 2d kaplama oldugunu belirtiyor
Kaplamalar 1d 2d 3d olabilir. Ama biz bu ders icin 2d kaplama kullanacaz. yani U ve V koordinatları
olacak.Polygonumuzu cizerken koordinatları 2 boyutlu olarak vericez.
*/
glBindTexture(GL_TEXTURE_2D, kaplamalar[kaplamaNO]);
/*
Bu kısımda ise bagladıgımız bitmap ten mipmap ler yaratmamız lazım.Mipmap dedigimiz teknikte
bir bitmapin birden fazla boyutlarda kopyaları yaratılır. Bu boyutlar sayesinde eger kaplamadan uzaklasırsak
kücük boyuttaki bitmap gosterilir. Yaklasırsakta büyük olanı gosterilir. Bu anlasılacagı üzere hafızayı daha fazla kullanan
bir tekniktir ama getirdigi avantajlar yanında hafızayı kullanmak cok daha karlıdır. Cünkü mipmap teknigini kullanmazsak
uzak kaplamalar birbirini üstüne binmeyebaslar ve bu ciddi bi performans kaybına neden olur.
gluBuild2DMipmaps in aldıgı degerler tamamen bizim auxDIBImageLoad ile cektigimiz degerleri gerektirir. 2 nin
katı olarak secmekte fayda vardır bitmapi. Yoksa mipmap olustururken sorun yasanabilir.
*/
gluBuild2DMipmaps(GL_TEXTURE_2D, 3, hBMP->sizeX, hBMP->sizeY, GL_RGB, GL_UNSIGNED_BYTE, hBMP->data);
/*
Bir diger özelikte kaplamamıza verecegimiz kalite olacaktır. MIN ve MAG filterlarına ayrı ozellikler veriirz
GL_LINEAR_MIPMAP_LINEAR en kalitelisi olup, GL_LINEAR_MIPMAP_NEAREST ise kalitesi düsük ama performansı yüksek olandır.
MIN fitresi o anki kaplanmıs pixel birden fazla kaplama birimine gelirse. Max filtresi ise o anki kaplanmıs
pixel birden az veya esit kaplama birimine gelirse.
*/
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR_MIPMAP_LINEAR);
/*
son olarakta tüm ayırıdıgımız hafızayı geri kazandıyıoruz sisteme
*/
if (hBMP)
{
if (hBMP->data)
{
free(hBMP->data);
}
free(hBMP);
}
}
OpenGL_Ders_3.cpp
C/C++ kodu:
/*
NOT : Bu sayfadaki fonksiyonları ve ana sistemi anlamak için win32 programlamaya
giriş i okumanızı tavsiye ederiz.
*/
#include "stdafx.h"
#include "Opengl_ders_3.h"
#include "Kaplama.h"
ATOM MyRegisterClass(HINSTANCE hInstance);
BOOL InitInstance(HINSTANCE, int);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK About(HWND, UINT, WPARAM, LPARAM);
// Global olarak kullanılacak Değişkenler
TCHAR szTitle[100]; // Başlık barındaki yazı
TCHAR szWindowClass[100]; // ana pencernin class ismi
//global nadir olarak değişen ve pencere ile alakalı değişkenler
HINSTANCE hInst;
HDC hdc; // Handle Device Context
HWND hWnd;// Handle Window;
HGLRC hrc; // Handle Rendering Context
int TamEkran = 0;// Tam ekran mı değilmi, sadece init te kullanılmak üzere
RECT winRect;// Pencerenin boyutlarını barındıran değişken, her pencerenin boyutu değiştiğinde bu değişkende güncellenir
#pragma comment(lib, "opengl32.lib") // gerekli opengl32 kütüphanesini include ediyoruz
#pragma comment(lib, "glu32.lib")// gerekli glu32 kütüphanesini include ediyoruz
#pragma comment(lib, "glaux.lib")// BMP i okumak icin gerekli olan API i kullanmak icin glaux kütüphanesini eklioruz
// winmain fonksiyonu
int APIENTRY _tWinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
{
LoadString(hInstance, IDS_APP_TITLE, szTitle, 100);
LoadString(hInstance, IDC_OPENGL_DERS_3, szWindowClass, 100);
MyRegisterClass(hInstance);
if (TamEkran)// tam ekransa ekran modunu baslangickodu.h da belirledigimiz degerlere dönüştür
EkranModunuDegistir();
if (!InitInstance(hInstance, nCmdShow))
{
return FALSE;
}
// pencerenin client bölügesinin koordinatlarını winRect rectangele ına doldur
GetClientRect(hWnd, &winRect);
// opengl ile alakalı tüm initialize lar burda
OpenGLINIT(EkranGenis, EkranYuksek);
// Programın başında gerekli kaplamayı yaratıyoruz.
KaplamaYarat(Kaplamalar, 0, "stone.bmp");
MSG msg;
// Ana oyun döngümüz, bu bölüm win32 e giriş dersinde anlatılmıştır.
while (1)
{
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
if (msg.message != WM_QUIT)
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
break;
}
else
{
Render();
}
}
return (int)msg.wParam;
}
// Pencereyi register etmek için kullanılan fonksiyon
// .Net ortamında win32 project i olusturunca kendiliginden yaratılan fonksyion
ATOM MyRegisterClass(HINSTANCE hInstance)
{
WNDCLASSEX wcex;
hInst = hInstance;
ZeroMemory(&wcex, sizeof(wcex));
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
wcex.lpfnWndProc = (WNDPROC)WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(hInstance, (LPCTSTR)IDI_OPENGL_DERS_3);
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wcex.lpszMenuName = (LPCTSTR)IDC_OPENGL_DERS_3;
wcex.lpszClassName = szWindowClass;
wcex.hIconSm = LoadIcon(wcex.hInstance, (LPCTSTR)IDI_SMALL);
return RegisterClassEx(&wcex);
}
//
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
hInst = hInstance; // instance handle ını global olarak tanımladıgımız hInst degiskenine ata
DWORD dwstyle;
if (TamEkran) // eger tam ekransa pencerenin style nı assagidaki gibi ayarla, pop up window olsun
dwstyle = WS_POPUPWINDOW | WS_CLIPSIBLINGS | WS_CLIPCHILDREN;
else // eger tam ekran değilse pencerenin style nı overlapped window yap
dwstyle = WS_OVERLAPPEDWINDOW | WS_CLIPSIBLINGS | WS_CLIPCHILDREN;
// Ana pencereyi Yarat, belirttigimiz dwStyle ı burda kullanıcaz, 3. parametre
// 1. parametre : pencerenin class ismi
// 2.parametre : başlık olarak gözükecek olan char array
// 3.parametre : bi önceki if durumunda belirttiğimiz dwStyle
// 4.parametre : pencerenin Sol üst pozisyonun X koordinatı
// 5.parametre : pencerenin Sol üst pozisyonun Y koordinatı
// 6.parametre : pencrenin genişliği
// 7.parametre : pencerenin yüksekliği
hWnd = CreateWindow(szWindowClass, szTitle, dwstyle,
0, 0, EkranGenis, EkranYuksek, NULL, NULL, hInstance, NULL);
if (!hWnd)
{
return FALSE;
}
ShowWindow(hWnd, nCmdShow); //pencereyi görülebilir yap
UpdateWindow(hWnd); // pencereyi güncelle
SetFocus(hWnd); // Klavye focusunu pencereye ver
return TRUE;
}
// WndProc //
//---------- //
// Görev : Ana pencere için gelecek mesajları işlemek
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
int wmId, wmEvent;
PAINTSTRUCT ps;
LONG lRet = 0;
POINT nokta;
switch (message)
{
case WM_CREATE: // pencere yaratıldığında gelen mesajı burda yakalıyoruz
MessageBox(NULL, "Pencere yaratıldı", "OK", NULL);
break;
case WM_SIZE: // pencerenin boyutu değiştiğinde ve ilk pencere yaratıldığında gelen mesaj
// çünkü her pencere yaratılırken bir kere resize olur
// Pencerenin yeni boyutunu winRect değişkenine doldur
// Yalnız pencerenin client kısmını yani pencerenin ortasındaki boş alanı (Bu örnekte menünün altındaki alan)
// Böylece herhangi bir çizim yaptıgımızda Y eksenini 0 aldıgımızda, menünün altındaki pixelden çizim başlıyacak.
//yani menünün altındaki ilk pixel 0 koordinatına denk gelecektir.
GetClientRect(hWnd, &winRect);
break;
case WM_MOUSEMOVE: // fare hareket ettiginde gelen mesajdır.
break;
case WM_KEYDOWN: // Keyboard da herhangi bir tusa basınca gelen mesaj.
switch (wParam) // wParam parametresi hangi tuşa basıldı ise o tuşun virtual key ini veriyor
{
}
break;
case WM_COMMAND:
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
switch (wmId)
{
case IDM_ABOUT: // önceden belirlenen About barına basınca yapılacaklar
// Dialogue box yaratır, böylece hangi ders olduğunu okuyabilirsiniz.
DialogBox(hInst, (LPCTSTR)IDD_ABOUTBOX, hWnd, (DLGPROC)About);
break;
case IDM_EXIT: // programdan cıktıgımız zaman
DestroyWindow(hWnd);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
break;
case WM_PAINT: // pencerenin tekrardan çizilmeye ihtiyacı duyulduğunda gelen mesaj
hdc = BeginPaint(hWnd, &ps);
// GDI kullanılarak yapılacak çizim işlemleri buraya
EndPaint(hWnd, &ps);
break;
case WM_DESTROY: // pencere kapanmak üzere iken gelen mesaj
OpenGLDEINIT(); // opengl in ayırdığı kaynakları geri verme zamanı
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
//Hakkinda kutusu icin mesaj işleyici, bi yukardaki ana pencereninki ile aynı formattadır
// yukardaki hatırlıyacagımız üzere ana pencerenin mesaj işleyicisidir, bu ise sadece hakkında penceresi içindir.
LRESULT CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_INITDIALOG:
return TRUE;
case WM_COMMAND:
if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
{
EndDialog(hDlg, LOWORD(wParam));
return TRUE;
}
break;
}
return FALSE;
}
Render.cpp
C/C++ kodu:
#include "Opengl_ders_3.h"
#include "Render.h" // YENI olarak render.h ı ekledik, artık Render.cpp dosyasında yer alacak fonksiyonlarda
// kullanacagımız değişkenleri burada tutucaz
// RENDER //
//----------//
/*
GÖREV : Tüm çizim fonksiyonlarını barındıran ana fonksiyon
NOT :Bundan sonra tüm OPENGL Derslerinde bu kod yapısı kullanılacak
yani yeni şeyler bu yapının üstüne inşa edilecektir.
*/
void Render()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Ekran ve derinlik buffer bitini sıfırla
glLoadIdentity(); // Aktif olan matrixi identity yap, yani resetle
//Opengl icin ekranı sildigi renk, yani boyanmamıs alanın renk
//kırmızı//yeşil//mavi//alfa
glClearColor(0.0f, 0.0f, 1.0f, 0.0f);
if (!TamEkran) // eger tam ekran ise her render da ortho ve viewport u güncellememize gerek yok
// fakat pencere modda, pencerenin boyutu her degistiginde viewport ve glortho fonksiyonlarını
//cagırmamız gerekiyor yoksa pencereyi genişlettigimizde çizimlerde genişler.Istenilen bir
//durum değil tabiki Fakat şimdilik karısmasın diye her render da glOrtho ve glViewport fonksiyonlarını kullandım
{
OpenGLEkranAyarla(winRect.right, winRect.bottom);
}
// 2d kaplama yapmak istediigmiz zaman bu özelligi enable etmemiz gerekiyor
glEnable(GL_TEXTURE_2D);
// Kaplamalar dizisine kaydettiğimiz ilk kaplamayı yani 0. indexteki kaplamayı aktif kaplama yap
glBindTexture(GL_TEXTURE_2D, Kaplamalar[0]);
// ekrana bi kare cizelim
glBegin(GL_QUADS);
/* simdi burda farklı olarak glTexCoord2f fonksiyonu var. Bu fonksyion her vertexten önce cagrılması gerekiyor
Bu fonksiyon kaplamanın koordinatları olmaktarır. float tipi olarak 0 ile 1 arasında degisir. Simdi karemizin sol
alt koordinatı 10,266 dır.kaplama koordinatları sol alt köşesi 0,0 olarak kabul edilir.Yalnız burada dikkat: 10,266
karenin sol alt noktasıdır. Pencere koordinatı ise sol yukarıyı origin olarak alır yani 0,0. Dogal olarak 10,266
karenin sol alt köşesidir. Fakat kaplama koordinatı için ise sol alt köşe origindir. 0,0 yani. O yüzden karenin
sol alt köşesi icin 0,0 kullanılır.
Cünkü
*/
// Karenin sol alt noktası
glTexCoord2f(0.0f, 0.0f);
glVertex2f(10, 100);
// Karenin sol üst noktası
glTexCoord2f(0.0f, 1.0f);
glVertex2f(10, 10);
// Karenin sag üst noktası
glTexCoord2f(1.0f, 1.0f);
glVertex2f(100, 10);
// Karenin sag alt noktası
glTexCoord2f(1.0f, 0.0f);
glVertex2f(100, 100);
glEnd();
SwapBuffers(hdc); // arka bufferı öndeki ile degistiriyoruz, şu ana kadar arka buffer a yazdık
//sonra onu ön buffer yapıp render ediyoruz, o render olurken arkadakini tekrar aynı
//sekilde dolduruyoruz ve işlem böyle devam ediyor
}
/*
pencere koordinatı:
------------------
0,0 genişlik,0
----------------------------
| |
| |
| |
| |
| |
----------------------------
yükseklik,0 genişlik,yükseklik
kaplama koordinatı:
------------------
0,1 1,1
---------
| |
| |
| |
| |
---------
0,0 1,0
*/
http://www.mediafire.com/download/y4q1ssf17u1nqmt/OpenGL_Ders_3.rar
Levent A. Sevgili
Yorumlar
Yorum Gönder