image.png

image.png

location은 여기서 쉐이더를 각각 연결하도록 하는 것임을 기억하도록

image.png

#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>
#include <iostream>
#include <fstream>
#include <string>

GLuint VBO, VAO, EBO, shaderProgram;

// Read shader file
std::string ReadFile(const char* filePath) {
    std::ifstream file(filePath, std::ios::in);
    if (!file.is_open()) {
        std::cerr << "Failed to open file: " << filePath << std::endl;
        return "";
    }

    std::string content, line;
    while (std::getline(file, line)) {
        content += line + "\\n";
    }
    file.close();
    return content;
}

// Compile and link shader program
GLuint CreateShaderProgram(const char* vertexPath, const char* fragmentPath) {
    std::string vsCode = ReadFile(vertexPath);
    std::string fsCode = ReadFile(fragmentPath);

    GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
    const char* vsSource = vsCode.c_str();
    glShaderSource(vertexShader, 1, &vsSource, NULL);
    glCompileShader(vertexShader);

    GLint success;
    glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success);
    if (!success) {
        char infoLog[512];
        glGetShaderInfoLog(vertexShader, 512, NULL, infoLog);
        std::cerr << "Error compiling vertex shader: " << infoLog << std::endl;
    }

    GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
    const char* fsSource = fsCode.c_str();
    glShaderSource(fragmentShader, 1, &fsSource, NULL);
    glCompileShader(fragmentShader);

    glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success);
    if (!success) {
        char infoLog[512];
        glGetShaderInfoLog(fragmentShader, 512, NULL, infoLog);
        std::cerr << "Error compiling fragment shader: " << infoLog << std::endl;
    }

    GLuint program = glCreateProgram();
    glAttachShader(program, vertexShader);
    glAttachShader(program, fragmentShader);
    glLinkProgram(program);

    glGetProgramiv(program, GL_LINK_STATUS, &success);
    if (!success) {
        char infoLog[512];
        glGetProgramInfoLog(program, 512, NULL, infoLog);
        std::cerr << "Error linking program: " << infoLog << std::endl;
    }

    glDeleteShader(vertexShader);
    glDeleteShader(fragmentShader);

    return program;
}

// Cube data -> 이렇게 하면 앞(x,y,z), 뒤(r,g,b) 가능한데 이때 가능한 이유가 어차피 glVertextAttriibpointer를 사용해서 각 속성 정의 가능 
void CreateCube() {
    GLfloat vertices[] = {
        // Positions          // Colors
        -1.0f, -1.0f,  1.0f,  1.0f, 0.0f, 0.0f,
         1.0f, -1.0f,  1.0f,  0.0f, 1.0f, 0.0f,
         1.0f,  1.0f,  1.0f,  0.0f, 0.0f, 1.0f,
        -1.0f,  1.0f,  1.0f,  1.0f, 1.0f, 0.0f,

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

    GLuint indices[] = {
        // Front face
        0, 1, 2, 2, 3, 0, // 예를 들어서 삼각형 0,1,2 이어서 한개, 2,3,0 이어서 한개로 총 삼각형 2개로 사각형 1개인 면 생성
        // Back face
        4, 5, 6, 6, 7, 4,
        // Left face
        4, 5, 3, 3, 0, 4,
        // Right face
        1, 2, 6, 6, 7, 1,
        // Top face
        3, 2, 6, 6, 5, 3,
        // Bottom face
        4, 7, 1, 1, 0, 4,
    };

    glGenVertexArrays(1, &VAO);
    glBindVertexArray(VAO);

    glGenBuffers(1, &VBO);
    glBindBuffer(GL_ARRAY_BUFFER, VBO);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

    glGenBuffers(1, &EBO); //인덱스 버퍼로 만들어서 데이터 사용
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);

    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (void*)0); //여기서 처음에 0은 location을 의미하고 이후 쉐이더로 입력하도록 하는 것 
    glEnableVertexAttribArray(0);

    glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (void*)(3 * sizeof(GLfloat))); //(여기서 아까 위에서 앞,뒤 나눴던 것을 3개씩 끊어서 가져가도록 하는 것) 분할이 가능하다는 것을 알아두면 될 듯
    glEnableVertexAttribArray(1);

    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glBindVertexArray(0);
}

int main() {
    if (!glfwInit()) return -1;

    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 5);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);

    GLFWwindow* window = glfwCreateWindow(800, 600, "Cube Example", NULL, NULL);
    if (!window) return -1;

    glfwMakeContextCurrent(window);
    if (glewInit() != GLEW_OK) return -1;

    shaderProgram = CreateShaderProgram("shader.vert", "shader.frag");
    CreateCube();

    glEnable(GL_DEPTH_TEST);

    while (!glfwWindowShouldClose(window)) {
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

        glUseProgram(shaderProgram);

        glm::mat4 model = glm::mat4(1.0f);
        glm::mat4 view = glm::lookAt(
            glm::vec3(3.0f, 3.0f, 3.0f),
            glm::vec3(0.0f, 0.0f, 0.0f),
            glm::vec3(0.0f, 1.0f, 0.0f)
        );
        glm::mat4 projection = glm::perspective(
            glm::radians(45.0f), 800.0f / 600.0f, 0.1f, 100.0f
        );
        glm::mat4 mvp = projection * view * model;

        GLuint mvpLoc = glGetUniformLocation(shaderProgram, "MVP");
        glUniformMatrix4fv(mvpLoc, 1, GL_FALSE, glm::value_ptr(mvp));

        glBindVertexArray(VAO);
        glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_INT, 0);
        glBindVertexArray(0);

        glfwSwapBuffers(window);
        glfwPollEvents();
    }

    glfwTerminate();
    return 0;
}

메인코드

#version 460

in vec3 fragmentColor;
out vec4 color;

void main() {
    color = vec4(fragmentColor, 1.0);
}

shader.frag

#version 460

layout(location = 0) in vec3 pos;
layout(location = 1) in vec3 vertexColor;

out vec3 fragmentColor;

uniform mat4 MVP;

void main() {
    gl_Position = MVP * vec4(pos, 1.0);
    fragmentColor = vertexColor;
}

shader.vert

예외로 알아서 회전하는 방식으로 설정

#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>
#include <iostream>
#include <fstream>
#include <string>
#include <chrono> // 시간 측정을 위해 사용

GLuint VBO, VAO, EBO, shaderProgram;

// Read shader file
std::string ReadFile(const char* filePath) {
    std::ifstream file(filePath, std::ios::in);
    if (!file.is_open()) {
        std::cerr << "Failed to open file: " << filePath << std::endl;
        return "";
    }

    std::string content, line;
    while (std::getline(file, line)) {
        content += line + "\\n";
    }
    file.close();
    return content;
}

// Compile and link shader program
GLuint CreateShaderProgram(const char* vertexPath, const char* fragmentPath) {
    std::string vsCode = ReadFile(vertexPath);
    std::string fsCode = ReadFile(fragmentPath);

    GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
    const char* vsSource = vsCode.c_str();
    glShaderSource(vertexShader, 1, &vsSource, NULL);
    glCompileShader(vertexShader);

    GLint success;
    glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success);
    if (!success) {
        char infoLog[512];
        glGetShaderInfoLog(vertexShader, 512, NULL, infoLog);
        std::cerr << "Error compiling vertex shader: " << infoLog << std::endl;
    }

    GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
    const char* fsSource = fsCode.c_str();
    glShaderSource(fragmentShader, 1, &fsSource, NULL);
    glCompileShader(fragmentShader);

    glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success);
    if (!success) {
        char infoLog[512];
        glGetShaderInfoLog(fragmentShader, 512, NULL, infoLog);
        std::cerr << "Error compiling fragment shader: " << infoLog << std::endl;
    }

    GLuint program = glCreateProgram();
    glAttachShader(program, vertexShader);
    glAttachShader(program, fragmentShader);
    glLinkProgram(program);

    glGetProgramiv(program, GL_LINK_STATUS, &success);
    if (!success) {
        char infoLog[512];
        glGetProgramInfoLog(program, 512, NULL, infoLog);
        std::cerr << "Error linking program: " << infoLog << std::endl;
    }

    glDeleteShader(vertexShader);
    glDeleteShader(fragmentShader);

    return program;
}

// Cube data
void CreateCube() {
    GLfloat vertices[] = {
        // Positions          // Colors
        -1.0f, -1.0f,  1.0f,  1.0f, 0.0f, 0.0f,
         1.0f, -1.0f,  1.0f,  0.0f, 1.0f, 0.0f,
         1.0f,  1.0f,  1.0f,  0.0f, 0.0f, 1.0f,
        -1.0f,  1.0f,  1.0f,  1.0f, 1.0f, 0.0f,

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

    GLuint indices[] = {
        // Front face
        0, 1, 2, 2, 3, 0,
        // Back face
        4, 5, 6, 6, 7, 4,
        // Left face
        4, 5, 3, 3, 0, 4,
        // Right face
        1, 2, 6, 6, 7, 1,
        // Top face
        3, 2, 6, 6, 5, 3,
        // Bottom face
        4, 7, 1, 1, 0, 4,
    };

    glGenVertexArrays(1, &VAO);
    glBindVertexArray(VAO);

    glGenBuffers(1, &VBO);
    glBindBuffer(GL_ARRAY_BUFFER, VBO);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

    glGenBuffers(1, &EBO);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);

    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (void*)0);
    glEnableVertexAttribArray(0);

    glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (void*)(3 * sizeof(GLfloat)));
    glEnableVertexAttribArray(1);

    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glBindVertexArray(0);
}

int main() {
    if (!glfwInit()) return -1;

    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 5);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);

    GLFWwindow* window = glfwCreateWindow(800, 600, "Rotating Cube", NULL, NULL);
    if (!window) return -1;

    glfwMakeContextCurrent(window);
    if (glewInit() != GLEW_OK) return -1;

    shaderProgram = CreateShaderProgram("shader.vert", "shader.frag");
    CreateCube();

    glEnable(GL_DEPTH_TEST);

    // 시간 측정 초기화
    auto lastTime = std::chrono::high_resolution_clock::now();
    float rotationAngle = 0.0f; // 초기 회전 각도

    while (!glfwWindowShouldClose(window)) {
        auto currentTime = std::chrono::high_resolution_clock::now();
        float deltaTime = std::chrono::duration<float>(currentTime - lastTime).count();
        lastTime = currentTime;

        // 회전 각도 업데이트
        rotationAngle += 50.0f * deltaTime; // 초당 50도 회전
        if (rotationAngle > 360.0f) rotationAngle -= 360.0f;

        // 화면 클리어
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

        glUseProgram(shaderProgram);

        glm::mat4 model = glm::rotate(glm::mat4(1.0f), glm::radians(rotationAngle), glm::vec3(1.0f, 1.0f, 0.0f));
        glm::mat4 view = glm::lookAt(
            glm::vec3(3.0f, 3.0f, 3.0f),
            glm::vec3(0.0f, 0.0f, 0.0f),
            glm::vec3(0.0f, 1.0f, 0.0f)
        );
        glm::mat4 projection = glm::perspective(
            glm::radians(45.0f), 800.0f / 600.0f, 0.1f, 100.0f
        );
        glm::mat4 mvp = projection * view * model;

        GLuint mvpLoc = glGetUniformLocation(shaderProgram, "MVP");
        glUniformMatrix4fv(mvpLoc, 1, GL_FALSE, glm::value_ptr(mvp));

        glBindVertexArray(VAO);
        glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_INT, 0);

        glfwSwapBuffers(window);
        glfwPollEvents();
    }

    glfwTerminate();
    return 0;
}


이제 texture를 입혀서 확인해 볼 생각

→ 2d 이미지에 texture 입히는 것 6번 or CubeMap확인 해서 하는 방법

https://heinleinsgame.tistory.com/29