OpenGL'de Shader Kullanımı


OpenGL_Ders_5.h 

C/C++ kodu:

#ifndef INC_DERS4_H
#define INC_DERS4_H

#include "resource.h"
#include <windows.h>
#include <stdlib.h>
#include <math.h>            // matematik fonksiyonları için başlık dosyası
#include "GLEWincludeglglew.h"    // SHADER i rahatca kullanmak icin ekledigimiz Wrangler kütühanesi
#include <glgl.h>            // OpenGL32 kütüphanesi icin baslik dosyası
#include <glglu.h>            // GLU32 kütüphanesi icin baslik dosyası
#include <vector>
#include <string>

using namespace std; // string yapısını rahat sekilde kullanmak icin

#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 float Degisken;


// Vektor2f icin gerekli tanımlama
struct Vektor2f
{
    float xy[2];
    Vektor2f operator + (const Vektor2f °isken);
    Vektor2f operator - (const Vektor2f °isken);
    Vektor2f operator * (const Vektor2f °isken);
};

string DosyayiOku(char *dosyaYolu);


extern HINSTANCE hInst;
extern HDC hdc;
extern HWND hWnd;
extern HGLRC hrc;
extern TCHAR szWindowClass[100];
extern RECT winRect;
extern int TamEkran;
extern POINT farePoz;


extern string sPixShader;
extern string sVerShader;

extern GLhandleARB hVertexShader;
extern GLhandleARB hPixelShader;
extern GLhandleARB hProgramObjesi;

extern int t;

// 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();
#endif

Render.h

C/C++ kodu:
#ifndef INC_RENDER_H
#define INC_RENDER_H
 
POINT farePoz ;
string sPixShader;
string sVerShader;
static float ft;
int t;
float Degisken;
//Vertex shaderin bilgisini tutan handle (tutamaç)
GLhandleARB hVertexShader;
//Fragment shader bilgisini tutan handle
GLhandleARB hPixelShader;
//Program bilgisini tutan handle
GLhandleARB hProgramObjesi;
 
#endif

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_5.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
    // FOV    // Ratio    //  the farthest distance before it stops drawing).
    gluPerspective(45.0f, (GLfloat)winRect.right / (GLfloat)winRect.bottom, .5f, 150.0f);
    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
}
 
OpenGL_Ders_5.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_5.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 = 1;// 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, "glew32.lib") // glew kütüphanesi ekran kartnın shader ı destekleyip desteklemedigini daha rahat kullanmak icin
#pragma comment(lib, "glaux.lib") 

// 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_5, 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);



    // glew ICIN INIT
    GLenum err = glewInit();
    if (GLEW_OK != err)
    {
        // Kullanacagımız Opengl extension larından birincisi, eger yoksa mesaj verip programdan çık
        if (!glewIsSupported("GL_ARB_fragment_program"))
        {
            MessageBox(hWnd, "GL_ARB_fragment_program desteklenmiyor", "HATA", NULL);
            PostQuitMessage(0);
        }
        // Kullanacagımız Opengl extension larından ikincisi, eger yoksa mesaj verip programdan çık
        if (!glewIsSupported("GL_ARB_shading_language_100"))
        {
            MessageBox(hWnd, "GL_ARB_shading_language_100 desteklenmiyor", "HATA", NULL);
            PostQuitMessage(0);

        }

    }


    //2 tane shader objesi yaratıyoruz, birincisi vertex shader için ikincisi pixel shader için
    hVertexShader = glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB);
    hPixelShader = glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB);

    // 2 tanede shader dosyası yaratmıstık. Bunları yarattıgımız DosyayiOku fonksiyonu ile
    // okuyarak tüm dosyayı bir string olarak sVerShader ve sPixShader olarak kaydediyoruz.
    sVerShader = DosyayiOku("VertexShader.vs");
    sPixShader = DosyayiOku("PixelShader.ps");

    //glShaderSourceARB fonksiyonunda kullanabilmek bu 2 stringten 2 tanede char göstergesi yaratıoruz
    const char *dpVertexShader = sVerShader.c_str();
    const char *dpPixelShader = sPixShader.c_str();


    // glShaderSourceARB fonksiyonu ile yarattigimiz stringleri alakalı yarattıgımız pointerlarla ilişkilendirioruz
    glShaderSourceARB(hVertexShader, 1, &dpVertexShader, NULL);
    glShaderSourceARB(hPixelShader, 1, &dpPixelShader, NULL);

    // Burda ilişkilendirdigimiz objeleri compile ediyoruz.
    glCompileShaderARB(hVertexShader);
    glCompileShaderARB(hPixelShader);

    // Burda shaderları gostermek amacıyla bi program ojesi yaratıoruz
    hProgramObjesi = glCreateProgramObjectARB();

    // yaratip icinide dosyadan okudugumuz stringle doldurdugumuz shader objelerini ana program objesi ile ilişkilendirioruz
    glAttachObjectARB(hProgramObjesi, hVertexShader);
    glAttachObjectARB(hProgramObjesi, hPixelShader);

    // Program objesini opngl ile ilişkilendiriyoruz
    glLinkProgramARB(hProgramObjesi);

    // glUseProgramObjectARB fonksyionu ile shader i açıyoruz. Eger 0 degerini alırsa shader kapanır.
    // glUseProgramObjectARB(hProgramObjesi); -> ACIK
    // glUseProgramObjectARB(0); -> KAPALI
    // Shader ı kodun herhangi yerinde kapatıp acabilioruz.
    glUseProgramObjectARB(hProgramObjesi);

    // Shader dosyasında belirledigimiz uniform float t; degiskeni yani dısarıdan degistirilebilen degiskeni
    // burda belirliyoruz.
    t = glGetUniformLocationARB(hProgramObjesi, "t");

    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_5);
    wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
    wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
    wcex.lpszMenuName = (LPCTSTR)IDC_OPENGL_DERS_5;
    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.

        // farenin pozsiyonunu al
        farePoz.x = LOWORD(lParam);
        farePoz.y = HIWORD(lParam);


        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
        {
        case VK_SPACE:// isimden anlasıldıgı üzere space tuşuna basılınca burası işlicek


            Degisken += 1.0f;

            break;

        }

        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
            if (hVertexShader)
            {
                glDetachObjectARB(hProgramObjesi, hVertexShader);
                glDeleteObjectARB(hVertexShader);
                hVertexShader = NULL;
            }

            // If our fragment shader pointer is valid, free it
            if (hPixelShader)
            {
                glDetachObjectARB(hProgramObjesi, hPixelShader);
                glDeleteObjectARB(hPixelShader);
                hPixelShader = NULL;
            }

            // If our program object pointer is valid, free it
            if (hProgramObjesi)
            {
                glDeleteObjectARB(hProgramObjesi);
                hProgramObjesi = NULL;
            }
            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_5.h"
#include "Render.h"
#include <string>
#include <glglaux.h>
using namespace std; // string yapısını rahat sekilde kullanmak icin
/*

Opengl_ders_5.h dosyasında tanımladıgımız Vektor2f yapısının overloaded operatorlerini burda tnaımladık
yani vektör toplama cıkarma ve carpma yapmak artık daha kolay olacak ÖRNEGIN :

Vektor2f vek1 ;
Vektor2f vek2 ;

Vektor2f vek3 ;


vek3.xy[0] = vek1.xy[0] + vek2.xy[0];
vek3.xy[1] = vek1.xy[1] + vek2.xy[1];

Yukardaki yerine alttaki cok daha kullanıslı ve aynı işi görecek

vek3 = vek1 + vek2;


*/
Vektor2f Vektor2f::operator + (const Vektor2f °isken)
{

    Vektor2f tmp;
    tmp.xy[0] = xy[0] + degisken.xy[0];
    tmp.xy[1] = xy[1] + degisken.xy[1];
    return tmp;

}

Vektor2f Vektor2f::operator - (const Vektor2f °isken)
{

    Vektor2f tmp;
    tmp.xy[0] = xy[0] - degisken.xy[0];
    tmp.xy[1] = xy[1] - degisken.xy[1];
    return tmp;

}

Vektor2f Vektor2f::operator * (const Vektor2f °isken)
{

    Vektor2f tmp;
    tmp.xy[0] = xy[0] * degisken.xy[0];
    tmp.xy[1] = xy[1] * degisken.xy[1];
    return tmp;

}





//  DosyayiOku  //
//----------//

// Shader icin dosyanın içindeki karakterleri string e atmamız gerekiyor
// Cünkü bu string i ekran kartına yüklememiz gerekecekki 
// her pixel veya her vertex icin calısan bi program olsun

string DosyayiOku(char *dosyaYolu)
{
    string DoldurulacakYazi;
    FILE *file = fopen(dosyaYolu, "r");

    while (!feof(file))
    {
        char karakter;
        fscanf(file, "%c", &karakter);
        DoldurulacakYazi.push_back(karakter);
    }
    DoldurulacakYazi.erase(DoldurulacakYazi.size() - 1);
    return DoldurulacakYazi;
}



//  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ını 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);

    // ft degiskeni dalgalanan yüzeyin dalgalanmasını saglayan counter
    ft += 0.1f;

    // Ekran kartı üzerine attıgımız programdaki t degiskenini ft degiskenine atıoruz
    glUniform1fARB(t, ft);


    // GLU dan quadratic formda objeler cizmek icin gösterge yaratıoruz
    // quadratic form dedigimiz cisimler: silindir küre koni vs.

    GLUquadricObj *pObj = gluNewQuadric();

    // Cizim tipini belirler, burda wire frame modda cizmek icin GLU_LINE secilmiştir.
    gluQuadricDrawStyle(pObj, GLU_LINE);
    // matrix stack ine yeni bi matrix atıoruz. Bundan sonraki transformla alakalı fonksiyonlar ana koordinat düzlemini degistirmicek
    glPushMatrix();
    glTranslatef(0.0f, 1.0f, -8.5f);    // Uygun bi pozisyon icin quadric in pozisyonunu degistirioruz
    glRotatef(Degisken, 1.0f, 1.0f, 1.0f);  // Space tusuna basılı tutunca tüm eksenlerde dönmesini saglıoruz
    glScalef(3.0f, 1.0f, 1.0f); // Quadric in boyutunu X ekseninde 3 kat büyültüyoruz.
    gluCylinder(pObj, 1.0f, 1.0f, 3.0f, 64, 32);     // Silindir ciziyoruz.
    //Sırasıyla :yaratılan quadratic objeye gösterge, alt tabakanın yaricapı, üst tabakanın yarıçapı, Yüksekligi
    // x ve y eksenindeki slice lar

    glPopMatrix(); // Matrix stack inden matrix i geri alıoruz.

    gluDeleteQuadric(pObj);    // yarattigimiz quadric i bosaltıoruz

    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

}

/*
Dosyadan okudugumuz 2 shader stringini programa atadıktan sonra programın istedigimiz yerinde bu shaderları on off yapabilioruz.
Init kısmında kullandıgımız fonksiyonlar da pek degisiklik yapılmaz esas degisiklik yapılacak yerler bizim shader dosyalarımız yani
VertexShader.vs ve PixelShader.ps dir. Her vertex icin VertexShader.vs kodu ve her pixel için ise PixelShader.ps kodu calısacaktır.
Buna göre gerekirse ısıklandırma gerekirse bump mapping vb. teknikleri kullanılabilir.

*/

http://www.mediafire.com/download/k6aai77jer6j4m2/OpenGL_Ders_5.rar

Levent A. Sevgili

Yorumlar

Bu blogdaki popüler yayınlar

SDL Nedir?

Doxygen Kullanımı

OpenGL'de Line (çizgi) Çizdirme