glfw3 3 boyutlu kamera

Keremss

Yeni üye
1 Ara 2020
10
0
25
Sakarya
Yardımcı kütüphane olarak glm'i kullandım

Kamera ve projeksiyon matrisini her cisim için çarpmanız gerekiyor

Programda sadece 2 cisim olduğu için pek bir şey belli olmuyor kusura bakmayın wasd ile kamerayı hareket ettirip fare ile baktığınız yönü değiştirebiliyorusunuz aslında.

Önce kütüphaneleri yüklüyoruz
Kod:
#include<glm/vec3.hpp>
#include<glm/gtc/matrix_transform.hpp>
#include<glm/glm.hpp>
#include<glad/glad.h>
#include<GLFW/glfw3.h>
Değişkenlerimizi tanımlıyoruz
Kod:
float windowWidth = 800.0f; //pencere genişliği
float windowHeight = 600.0f;  // pencere yüksekiği
float FOV = 90; // 90 fps bakış açısı için idealdir zoom gibi birşey
float mouseSpeed = 0.005f; // mouse hızı
float speed = 3.0f; // Kamera hızı

float horizontalAngle = 3.14f; // yatay açı
GLFWwindow* window = glfwCreateWindow(windowWidth,windowHeight,"FPS programı".c_str(),NULL,NULL); // window nesnesi

float verticalAngle = 0.0f; // dikey açı

glm::vec3 direction;
glm::vec3 right;
glm::vec3 up;

glm::vec3 camPosition = glm::vec3(0.0f,0.0f, 3.0f); // Kameranın kordinat düzlemindeki yeri
glm::vec3 camLookAt; // Kameranın kordinat düzleminde nereye bakacağını söyleyen değişken
glm::vec3 camUp = glm::vec3(0.0f, 1.0f, 0.0f);

glm::mat4 mtxProj = glm::perspective(glm::radians(FOV), windowWidth/windowHeight, 0.001f, 100.0f); // Kamera Perspektif matrisi
glm::mat4 mtxCam; // Kamera matrisi
Değişkenleri shadera bağlıyacağız
Kod:
// Program nesnesi oluşturmak için
unsigned int programID = glCreateProgram();

// Shaderdaki uniform değişkeni aktif olan program nesnesine bağlamak için aşağıdaki fonksiyon kullanılır

// glGetUniform******** fonksiyonu uint türünden bir id değeri gönderir değer atamak için bu id değerini kullanıcağız

// NOT: Shaderınızda da aynı isimde bir uniform değişken olması lazım

//           id değerini tutan değişken      program id|shaderdaki değişkenin ismi
unsigned int mtxProjID = glGetUniform********(ProgramID, "mtxProj".c_str());
unsigned int mtxCamID = glGetUniform********(ProgramID, "mtxCam".c_str());
not: program nesnesini sadece göstermek amaçlı oluşturdum program nesnesine shader bağlamadan uniform değişken yollayamazsınız

Main Loopunuzun üstüne bu kodları yazıyoruz
Kod:
double lastTime = glfwGetTime();
double currentTime = lastTime;

glEnable(GL_DEPTH_TEST); // Derinlik tesitini aktif ediyoruz aktif etmezsek arkadaki objeler öndeki objelerin önüne geçebilir

Main Loop kodları
Kod:
while(!glfwWindowsShouldClose(window)){
        lastTime = currentTime;
        currentTime = glfwGetTime();
        // Delta Zamanı
        deltaTime = currentTime - lastTime;

        // Mouse pozisyonunu alıyoruz
        double xpos, ypos;
        glfwGetCursorPos(window, &xpos, &ypos);

        
        // Mouse pozisyonunu sonraki döngü için başlangıç konumuna getiriyoruz
        glfwSetCursorPos(window, windowWidth/2, windowHeight/2);

        // Başlangıçdaki değişlenlere değerini veriyoruz
        horizontalAngle += mouseSpeed * float(windowWidth/2 - xpos );
        verticalAngle   += mouseSpeed * float( windowHeight/2 - ypos );

        glm::vec3 direction = glm::vec3(
        cos(verticalAngle) * sin(horizontalAngle), 
        sin(verticalAngle),
        cos(verticalAngle) * cos(horizontalAngle)
    );
    
    // Right vector
        right = glm::vec3(
        sin(horizontalAngle - 3.14f/2.0f), 
        0,
        cos(horizontalAngle - 3.14f/2.0f)
    );
        up = glm::cross( right, direction );

        glClearColor(0.0f, 0.4f, 0.7f, 1.0f); // Ekranı temizliyoruz
        glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);


        // Kameranın pozisyonunu değiştirmek için
        if(glfwGetKey(window, GLFW_KEY_W)==GLFW_PRESS){
            camPosition += direction * deltaTime * speed;
        }
        if(glfwGetKey(window, GLFW_KEY_S)==GLFW_PRESS){
            camPosition -= direction * deltaTime * speed;
        }
        if(glfwGetKey(window, GLFW_KEY_A)==GLFW_PRESS){
            camPosition -= right * deltaTime * speed;        }
        if(glfwGetKey(window, GLFW_KEY_D)==GLFW_PRESS){
            camPosition += right * deltaTime * speed;
        }
        if(glfwGetKey(window, GLFW_KEY_LEFT_SHIFT)==GLFW_PRESS){
            camPosition -= glm::vec3(0.0f, 3.0, 0.0f) * deltaTime * speed;
        }
        if(glfwGetKey(window, GLFW_KEY_SPACE)==GLFW_PRESS){
            camPosition += glm::vec3(0.0f, 3.0, 0.0f) * deltaTime * speed;
        }

        glUseProgram(programID); // Progamı aktif ediyoruz

        //Burda vertex array objecti aktif ediyoruz
        //glBindVertexArray(VAO);


        // Shaderdaki uniform değişkene değerini yolluyoruz
        //         degiskenin id si             adresi
        glUniformMatrix4fv(mtxCamID, 1, false, (GLfloat*)&mtxCam);
        glUniformMatrix4fv(mtxProjID, 1, false, (GLfloat*)&mtxProj);

        // çizim komutunu gönderiyoruz
        //glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_INT, 0);

        glfwSwapBuffers(window);

        glfwPollEvents();
}

Vertex Shader Kodları
Kod:
#version 330 core
layout (******** = 0) in vec3 inPosition;
layout (******** = 1) in vec4 inColor;

uniform mat4 mtxProj;
uniform mat4 mtxCam;

out vec4 color;
**** main()
{      
     gl_Position = mtxProj*mtxCam*vec4(inPosition, 1.0);
     color= inColor;
}
Matrislerin Vertex Shaderda çarpılmasının sebebi Vertex Shaderın ekran kartında çalıştırılıyor olmasındandır eğer matrisleri main loopda çarparsak bu çarpımları ekran kartı değil işlemci çarpar ve biz bunu istemiyoruz çünkü işlemci 3 boyutlu matris çarpımında çok yavaştır bu işi ekran kartı daha hızlı yapar

Fare imlecini görünmez yapmak için
Kod:
 glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_HIDDEN);

Finalde oluşacak görüntüler

NvxzSv.png


Nvxm90.md.png


NvxGzY.png
 
Üst

Turkhackteam.org internet sitesi 5651 sayılı kanun’un 2. maddesinin 1. fıkrasının m) bendi ile aynı kanunun 5. maddesi kapsamında "Yer Sağlayıcı" konumundadır. İçerikler ön onay olmaksızın tamamen kullanıcılar tarafından oluşturulmaktadır. Turkhackteam.org; Yer sağlayıcı olarak, kullanıcılar tarafından oluşturulan içeriği ya da hukuka aykırı paylaşımı kontrol etmekle ya da araştırmakla yükümlü değildir. Türkhackteam saldırı timleri Türk sitelerine hiçbir zararlı faaliyette bulunmaz. Türkhackteam üyelerinin yaptığı bireysel hack faaliyetlerinden Türkhackteam sorumlu değildir. Sitelerinize Türkhackteam ismi kullanılarak hack faaliyetinde bulunulursa, site-sunucu erişim loglarından bu faaliyeti gerçekleştiren ip adresini tespit edip diğer kanıtlarla birlikte savcılığa suç duyurusunda bulununuz.