Untitled

mail@pastecode.io avatar
unknown
c_cpp
2 years ago
18 kB
2
Indexable
Never
#include <iostream>
#include <glad/glad.h>

#include <GLFW/glfw3.h>
#include <cmath>
#include "include/Shader.h"
#define STB_IMAGE_IMPLEMENTATION
#include "include/stb_image.h"
//for matrix transformation
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>

void framebuffer_size_callback(GLFWwindow*,int,int);
void update(GLFWwindow*);
void key_callback_function(GLFWwindow*,int,int,int,int);
void process_input(GLFWwindow* window);
void mouse_callback(GLFWwindow* ,double ,double);
void scroll_callback(GLFWwindow* ,double ,double);

//glm::vec3 position;
const int SCR_WIDTH = 800;
const int SCR_HEIGHT = 600;

glm::vec3 cameraPos         = glm::vec3 (0.0f,0.0f,3.0f);
glm::vec3 cameraFront       = glm::vec3 (0.0f,0.0f,-1.0f);
glm::vec3 cameraUp          = glm::vec3 (0.0f,1.0f,0.0f);

//za glatkocu kamere imamo proteklo vreme
float deltaTime = 0.0f;
float lastTime = 0.0f;
float speed = 1.0f;

//za pokrete misa
bool firstMouse = true;
float yaw = -90.0f;
float pitch = 0.0f;
float lastX = SCR_WIDTH /2;
float lastY = SCR_HEIGHT /2;
float fov = 45.0f;

//lighting
glm::vec3 lightPos(1.2f, 1.0f, 2.0f);

int main() {

    glfwInit();

    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);

    GLFWwindow *window = glfwCreateWindow(SCR_WIDTH,SCR_HEIGHT,"Hello", nullptr, nullptr);
    if(window == nullptr){
        std::cout<<"FAILED TO CREATE WINDOW\n";
        glfwTerminate();
        return EXIT_FAILURE;
    }

    glfwMakeContextCurrent(window);
    glfwSetFramebufferSizeCallback(window,framebuffer_size_callback);
    glfwSetCursorPosCallback(window,mouse_callback);
    glfwSetScrollCallback(window,scroll_callback);
    //glfwSetKeyCallback(window,key_callback_function);

    if(!gladLoadGLLoader((GLADloadproc) glfwGetProcAddress)){
        std::cout<<"FAILED TO LOAD GLAD\n";
        glfwTerminate();
        return EXIT_FAILURE;
    }

    glfwSetInputMode(window,GLFW_CURSOR,GLFW_CURSOR_DISABLED);
    glEnable(GL_DEPTH_TEST);

    Shader lightingShader ("/home/mihailo/CLionProjects/GL_Vezbe/resources/shaders/colors.vert","/home/mihailo/CLionProjects/GL_Vezbe/resources/shaders/colors.frag");
    Shader lightCubeShader ("/home/mihailo/CLionProjects/GL_Vezbe/resources/shaders/lightCube.vert","/home/mihailo/CLionProjects/GL_Vezbe/resources/shaders/lightCube.frag");
    //FIXME
    //Popraviti slanje putanje da se ne stavljaju apsolutne putanje nego relativne ali od korena projekta!!!

    float vertices[] = {

            -0.5f, -0.5f, -0.5f,  0.0f,  0.0f, -1.0f,  0.0f,  0.0f,
            0.5f, -0.5f, -0.5f,  0.0f,  0.0f, -1.0f,  1.0f,  0.0f,
            0.5f,  0.5f, -0.5f,  0.0f,  0.0f, -1.0f,  1.0f,  1.0f,
            0.5f,  0.5f, -0.5f,  0.0f,  0.0f, -1.0f,  1.0f,  1.0f,
            -0.5f,  0.5f, -0.5f,  0.0f,  0.0f, -1.0f,  0.0f,  1.0f,
            -0.5f, -0.5f, -0.5f,  0.0f,  0.0f, -1.0f,  0.0f,  0.0f,

            -0.5f, -0.5f,  0.5f,  0.0f,  0.0f,  1.0f,  0.0f,  0.0f,
            0.5f, -0.5f,  0.5f,  0.0f,  0.0f,  1.0f,  1.0f,  0.0f,
            0.5f,  0.5f,  0.5f,  0.0f,  0.0f,  1.0f,  1.0f,  1.0f,
            0.5f,  0.5f,  0.5f,  0.0f,  0.0f,  1.0f,  1.0f,  1.0f,
            -0.5f,  0.5f,  0.5f,  0.0f,  0.0f,  1.0f,  0.0f,  1.0f,
            -0.5f, -0.5f,  0.5f,  0.0f,  0.0f,  1.0f,  0.0f,  0.0f,

            -0.5f,  0.5f,  0.5f, -1.0f,  0.0f,  0.0f,  1.0f,  0.0f,
            -0.5f,  0.5f, -0.5f, -1.0f,  0.0f,  0.0f,  1.0f,  1.0f,
            -0.5f, -0.5f, -0.5f, -1.0f,  0.0f,  0.0f,  0.0f,  1.0f,
            -0.5f, -0.5f, -0.5f, -1.0f,  0.0f,  0.0f,  0.0f,  1.0f,
            -0.5f, -0.5f,  0.5f, -1.0f,  0.0f,  0.0f,  0.0f,  0.0f,
            -0.5f,  0.5f,  0.5f, -1.0f,  0.0f,  0.0f,  1.0f,  0.0f,

            0.5f,  0.5f,  0.5f,  1.0f,  0.0f,  0.0f,  1.0f,  0.0f,
            0.5f,  0.5f, -0.5f,  1.0f,  0.0f,  0.0f,  1.0f,  1.0f,
            0.5f, -0.5f, -0.5f,  1.0f,  0.0f,  0.0f,  0.0f,  1.0f,
            0.5f, -0.5f, -0.5f,  1.0f,  0.0f,  0.0f,  0.0f,  1.0f,
            0.5f, -0.5f,  0.5f,  1.0f,  0.0f,  0.0f,  0.0f,  0.0f,
            0.5f,  0.5f,  0.5f,  1.0f,  0.0f,  0.0f,  1.0f,  0.0f,

            -0.5f, -0.5f, -0.5f,  0.0f, -1.0f,  0.0f,  0.0f,  1.0f,
            0.5f, -0.5f, -0.5f,  0.0f, -1.0f,  0.0f,  1.0f,  1.0f,
            0.5f, -0.5f,  0.5f,  0.0f, -1.0f,  0.0f,  1.0f,  0.0f,
            0.5f, -0.5f,  0.5f,  0.0f, -1.0f,  0.0f,  1.0f,  0.0f,
            -0.5f, -0.5f,  0.5f,  0.0f, -1.0f,  0.0f,  0.0f,  0.0f,
            -0.5f, -0.5f, -0.5f,  0.0f, -1.0f,  0.0f,  0.0f,  1.0f,

            -0.5f,  0.5f, -0.5f,  0.0f,  1.0f,  0.0f,  0.0f,  1.0f,
            0.5f,  0.5f, -0.5f,  0.0f,  1.0f,  0.0f,  1.0f,  1.0f,
            0.5f,  0.5f,  0.5f,  0.0f,  1.0f,  0.0f,  1.0f,  0.0f,
            0.5f,  0.5f,  0.5f,  0.0f,  1.0f,  0.0f,  1.0f,  0.0f,
            -0.5f,  0.5f,  0.5f,  0.0f,  1.0f,  0.0f,  0.0f,  0.0f,
            -0.5f,  0.5f, -0.5f,  0.0f,  1.0f,  0.0f,  0.0f,  1.0f
    };

    //pozicije kocki
    glm::vec3 cubePositions[] = {
            glm::vec3( 0.0f,  0.0f,  0.0f),
            glm::vec3( 2.0f,  5.0f, -15.0f),
            glm::vec3(-1.5f, -2.2f, -2.5f),
            glm::vec3(-3.8f, -2.0f, -12.3f),
            glm::vec3( 2.4f, -0.4f, -3.5f),
            glm::vec3(-1.7f,  3.0f, -7.5f),
            glm::vec3( 1.3f, -2.0f, -2.5f),
            glm::vec3( 1.5f,  2.0f, -2.5f),
            glm::vec3( 1.5f,  0.2f, -1.5f),
            glm::vec3(-1.3f,  1.0f, -1.5f)
    };
    //pozicije svetala
    glm::vec3 pointLightPositions[] = {
            glm::vec3( 0.7f,  0.2f,  2.0f),
            glm::vec3( 2.3f, -3.3f, -4.0f),
            glm::vec3(-4.0f,  2.0f, -12.0f),
            glm::vec3( 0.0f,  0.0f, -3.0f)
    };

    //unsigned int indexes[] = {
    //        0,1,2,
    //        0,2,3
    //};

    unsigned VBO,cubeVAO;

    glGenVertexArrays(1,&cubeVAO);          //napravi VAO
    glGenBuffers(1,&VBO);               //napravi bafer VBO

    glBindBuffer(GL_ARRAY_BUFFER,VBO);  //aktiviramo bafer
    glBufferData(GL_ARRAY_BUFFER,sizeof(vertices),vertices,GL_STATIC_DRAW); //posalji podatke na bafer

    glBindVertexArray(cubeVAO);             //aktiviraj VAO

    glVertexAttribPointer(0,3,GL_FLOAT,GL_FALSE,8*sizeof(float),(void*)0);
    glVertexAttribPointer(1,3,GL_FLOAT,GL_FALSE,8*sizeof(float),(void*)(3*sizeof(float)));
    glVertexAttribPointer(2,2,GL_FLOAT,GL_FALSE,8*sizeof(float),(void*)(6*sizeof(float)));
    glEnableVertexAttribArray(0);
    glEnableVertexAttribArray(1);
    glEnableVertexAttribArray(2);


    //generisanje za lightCube
    unsigned lightCubeVAO;
    glGenVertexArrays(1,&lightCubeVAO);
    glBindVertexArray(lightCubeVAO);

    glBindBuffer(GL_ARRAY_BUFFER,VBO);
    glVertexAttribPointer(0,3,GL_FLOAT,GL_FALSE,8*sizeof(float),(void*)0);
    glEnableVertexAttribArray(0);


    //texture
    unsigned int defuseMap;
    glGenTextures(1,&defuseMap);

    int width,height,nrComponents;
    unsigned char* data = stbi_load("/home/mihailo/CLionProjects/GL_Vezbe/resources/textures/container2.png",&width,&height,&nrComponents,0);
    if(data){
        GLenum format;
        if(nrComponents == 1)
            format = GL_RED;
        else if(nrComponents == 3)
            format = GL_RGB;
        else if(nrComponents = 4)
            format = GL_RGBA;

        glBindTexture(GL_TEXTURE_2D,defuseMap);
        glTexImage2D(GL_TEXTURE_2D,0,format,width,height,0,format,GL_UNSIGNED_BYTE,data);
        glGenerateMipmap(GL_TEXTURE_2D);

        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GLFW_REPEAT);
        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GLFW_REPEAT);
        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_LINEAR);
        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);

        stbi_image_free(data);
    }
    else{
        std::cerr<<"FAILED TO LOAD TEXTURE\n";
        stbi_image_free(data);
        //glfwTerminate();
    }

    unsigned int specularMap;
    glGenTextures(1,&specularMap);

    data = stbi_load("/home/mihailo/CLionProjects/GL_Vezbe/resources/textures/container2_specular.png",&width,&height,&nrComponents,0);
    if(data){
        GLenum format;
        if(nrComponents == 1)
            format = GL_RED;
        else if(nrComponents == 3)
            format = GL_RGB;
        else if(nrComponents = 4)
            format = GL_RGBA;

        glBindTexture(GL_TEXTURE_2D,specularMap);
        glTexImage2D(GL_TEXTURE_2D,0,format,width,height,0,format,GL_UNSIGNED_BYTE,data);
        glGenerateMipmap(GL_TEXTURE_2D);

        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GLFW_REPEAT);
        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GLFW_REPEAT);
        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_LINEAR);
        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);

        stbi_image_free(data);
    }
    else{
        std::cerr<<"FAILED TO LOAD TEXTURE\n";
        stbi_image_free(data);
        //glfwTerminate();
    }

    lightingShader.use();
    lightingShader.setInt("material.diffuse",0);
    lightingShader.setInt("material.specular",1);

    //**razvezivanje objekata**//
    //glBindBuffer(GL_ARRAY_BUFFER,0);    //razvezi bafer
    //glBindVertexArray(0);               //razvezi VAO


    //RENDER LOOP!!!
    while(!glfwWindowShouldClose(window)){
        glfwPollEvents();
        process_input(window);  //ako hocesmo da se jednom registruje jedan taster koristimo setKeyCallback
                                //ako zelimo da se na primer pomera sve vreme tako sto drzimo taster onda radimo preko process_input()
                                //jer se radi glfwGetKey() koji registruje sve dok se taster drzi!!!


        //brojimo frejmove i proteklo vreme
        float currentTime = glfwGetTime();
        deltaTime = currentTime - lastTime;
        lastTime = currentTime;

        glClearColor(0.0f,0.0f,0.0f,1.0f);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

        //aktivacija texture
        glActiveTexture(GL_TEXTURE0);
        glBindTexture(GL_TEXTURE_2D,defuseMap);

        glActiveTexture(GL_TEXTURE1);
        glBindTexture(GL_TEXTURE_2D,specularMap);

        //model,projekcija i pogled matrice,CAMERA
        //glm::mat4 model         = glm::mat4(1.0f);
        glm::mat4 view          = glm::mat4(1.0f);
        glm::mat4 projection    = glm::mat4(1.0f);
        glm::vec3 lightColor    = glm::vec3(1.0f,1.0f,1.0f);
        //glm::vec3 lightPos(sin(glfwGetTime())*2.0f, sin(glfwGetTime()), cos(glfwGetTime())*2.0f);

        view = glm::lookAt(cameraPos,cameraPos + cameraFront,cameraUp);
        projection = glm::perspective(glm::radians(fov),(float)SCR_WIDTH/SCR_WIDTH,0.1f,100.0f);

        //kocka
        lightingShader.use();
        lightingShader.setMat4("view",view);
        lightingShader.setMat4("projection",projection);
        lightingShader.setVec3("viewPos",cameraPos);
        lightingShader.setFloat("material.shininess",32.0f);

        // directional light
        lightingShader.setVec3("dirLight.direction", -0.2f, -1.0f, -0.3f);
        lightingShader.setVec3("dirLight.ambient", 0.05f, 0.05f, 0.05f);
        lightingShader.setVec3("dirLight.diffuse", 0.4f, 0.4f, 0.4f);
        lightingShader.setVec3("dirLight.specular", 0.5f, 0.5f, 0.5f);
        // point light 1
        lightingShader.setVec3("pointLights[0].position", pointLightPositions[0]);
        lightingShader.setVec3("pointLights[0].ambient", 0.05f, 0.05f, 0.05f);
        lightingShader.setVec3("pointLights[0].diffuse", 0.8f, 0.8f, 0.8f);
        lightingShader.setVec3("pointLights[0].specular", 1.0f, 1.0f, 1.0f);
        lightingShader.setFloat("pointLights[0].constant", 1.0f);
        lightingShader.setFloat("pointLights[0].linear", 0.09);
        lightingShader.setFloat("pointLights[0].quadratic", 0.032);
        // point light 2
        lightingShader.setVec3("pointLights[1].position", pointLightPositions[1]);
        lightingShader.setVec3("pointLights[1].ambient", 0.05f, 0.05f, 0.05f);
        lightingShader.setVec3("pointLights[1].diffuse", 0.8f, 0.8f, 0.8f);
        lightingShader.setVec3("pointLights[1].specular", 1.0f, 1.0f, 1.0f);
        lightingShader.setFloat("pointLights[1].constant", 1.0f);
        lightingShader.setFloat("pointLights[1].linear", 0.09);
        lightingShader.setFloat("pointLights[1].quadratic", 0.032);
        // point light 3
        lightingShader.setVec3("pointLights[2].position", pointLightPositions[2]);
        lightingShader.setVec3("pointLights[2].ambient", 0.05f, 0.05f, 0.05f);
        lightingShader.setVec3("pointLights[2].diffuse", 0.8f, 0.8f, 0.8f);
        lightingShader.setVec3("pointLights[2].specular", 1.0f, 1.0f, 1.0f);
        lightingShader.setFloat("pointLights[2].constant", 1.0f);
        lightingShader.setFloat("pointLights[2].linear", 0.09);
        lightingShader.setFloat("pointLights[2].quadratic", 0.032);
        // point light 4
        lightingShader.setVec3("pointLights[3].position", pointLightPositions[3]);
        lightingShader.setVec3("pointLights[3].ambient", 0.05f, 0.05f, 0.05f);
        lightingShader.setVec3("pointLights[3].diffuse", 0.8f, 0.8f, 0.8f);
        lightingShader.setVec3("pointLights[3].specular", 1.0f, 1.0f, 1.0f);
        lightingShader.setFloat("pointLights[3].constant", 1.0f);
        lightingShader.setFloat("pointLights[3].linear", 0.09);
        lightingShader.setFloat("pointLights[3].quadratic", 0.032);
        // spotLight
        lightingShader.setVec3("spotLight.position", cameraPos);
        lightingShader.setVec3("spotLight.direction", cameraFront);
        lightingShader.setVec3("spotLight.ambient", 0.0f, 0.0f, 0.0f);
        lightingShader.setVec3("spotLight.diffuse", 1.0f, 1.0f, 1.0f);
        lightingShader.setVec3("spotLight.specular", 1.0f, 1.0f, 1.0f);
        lightingShader.setFloat("spotLight.constant", 1.0f);
        lightingShader.setFloat("spotLight.linear", 0.09);
        lightingShader.setFloat("spotLight.quadratic", 0.032);
        lightingShader.setFloat("spotLight.cutOff", glm::cos(glm::radians(12.5f)));
        lightingShader.setFloat("spotLight.outerCutOff", glm::cos(glm::radians(15.0f)));

        glBindVertexArray(cubeVAO);
        for(int i = 0;i<10;i++){
            glm::mat4 model         = glm::mat4(1.0f);
            float angle = 20.0 * i;
            model = glm::translate(model,cubePositions[i]);
            model = glm::rotate(model,angle,glm::vec3(1.0f,0.3f,0.5f));
            lightingShader.setMat4("model",model);
            glDrawArrays(GL_TRIANGLES,0,36);

        }

        //izvor svetlosti(kocke)
        lightCubeShader.use();
        lightCubeShader.setVec3("lightColor",lightColor);
        lightCubeShader.setMat4("view",view);
        lightCubeShader.setMat4("projection",projection);
        glBindVertexArray(lightCubeVAO);
        for(int i=0;i<4;i++){
            glm::mat4 model = glm::mat4 (1.0f);
            model = glm::translate(model,pointLightPositions[i]);
            model = glm::scale(model,glm::vec3(0.2f));
            lightCubeShader.setMat4("model",model);
            glDrawArrays(GL_TRIANGLES,0,36);
        }



        //update(window);
        glfwSwapBuffers(window);
    }


    glDeleteVertexArrays(1,&lightCubeVAO);
    glDeleteVertexArrays(1,&cubeVAO);
    glDeleteBuffers(1,&VBO);
    lightingShader.deleteProgram();
    lightCubeShader.deleteProgram();
    glfwTerminate();
    return 0;

}

void framebuffer_size_callback(GLFWwindow* window,int width,int height){
    glViewport(0,0,width,height);
}

void key_callback_function(GLFWwindow* window,int key,int scancode,int action,int mode){

    if(key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) {
        glfwSetWindowShouldClose(window, true);
    }

    //if(key == GLFW_KEY_UP && action == GLFW_PRESS){
    //    position.y += 0.02f;
    //}
    //if(key == GLFW_KEY_DOWN && action == GLFW_PRESS){
    //    position.y -= 0.02f;
    //}
    //if(key == GLFW_KEY_LEFT && action == GLFW_PRESS){
    //    position.x -= 0.02;
    //}
    //if(key == GLFW_KEY_RIGHT && action == GLFW_PRESS){
    //    position.x += 0.02;
    //}
}

void update(GLFWwindow* window){

}
void process_input(GLFWwindow *window){
    if(glfwGetKey(window,GLFW_KEY_ESCAPE) == GLFW_PRESS){
        glfwSetWindowShouldClose(window,true);
    }
    float cameraSpeed = 2.5 * deltaTime * speed;
    if(glfwGetKey(window,GLFW_KEY_W) == GLFW_PRESS){
        cameraPos += cameraSpeed * cameraFront;
    }
    if(glfwGetKey(window,GLFW_KEY_S) == GLFW_PRESS){
        cameraPos -= cameraSpeed * cameraFront;
    }
    if(glfwGetKey(window,GLFW_KEY_A) == GLFW_PRESS){
        cameraPos -= glm::normalize(glm::cross(cameraFront,cameraUp)) * cameraSpeed;
    }
    if(glfwGetKey(window,GLFW_KEY_D) == GLFW_PRESS){
        cameraPos += glm::normalize(glm::cross(cameraFront,cameraUp)) * cameraSpeed;
    }
    if(glfwGetKey(window,GLFW_KEY_LEFT_SHIFT) == GLFW_PRESS){
        speed = 5.0f;
    }
    if(glfwGetKey(window,GLFW_KEY_LEFT_SHIFT) == GLFW_RELEASE){
        speed = 1.0f;
    }
    //FPS CAMERA LOOK
    //cameraPos.y = 0.0f;
}

void scroll_callback(GLFWwindow *window, double xoff, double yoff) {
    fov -= (float)yoff;
    if(fov < 15.0f)
        fov = 15.0f;
    if(fov > 45.0f)
        fov = 45.0f;
}

void mouse_callback(GLFWwindow * window, double xpos, double ypos) {
    if(firstMouse){
        lastX = xpos;
        lastY = ypos;
        firstMouse = false;
    }

    float xoffset = xpos - lastX;
    float yoffset = lastY - ypos;
    lastX = xpos;
    lastY = ypos;

    float sens = 0.05;
    xoffset *= sens;
    yoffset *= sens;

    yaw += xoffset;
    pitch += yoffset;

    if(pitch > 89.0f)
        pitch = 89.0f;
    if(pitch < -89.0f)
        pitch = -89.0f;

    glm::vec3 direction;
    direction.x = cos(glm::radians(yaw)) * cos(glm::radians(pitch));
    direction.y = sin(glm::radians(pitch));
    direction.z = sin(glm::radians(yaw)) * cos(glm::radians(pitch));
    cameraFront = glm::normalize(direction);

}