[c++] GLFW의 사용자 정의 셰이더 처리

GLFW는 OpenGL을 위한 다중 플랫폼 라이브러리로, 윈도우 생성, 사용자 입력 이벤트 처리, OpenGL 콘텍스트 관리 등을 지원합니다. GLFW를 통해 사용자 정의 셰이더를 처리할 수 있습니다.

GLFW 및 OpenGL 초기화

먼저 GLFW 및 OpenGL을 초기화해야 합니다. 아래 예제는 간단한 초기화 코드를 보여줍니다.

#include <glad/glad.h>
#include <GLFW/glfw3.h>

int main() {
    // GLFW 초기화
    glfwInit();

    // GLFW 버전 및 코어 프로필 설정
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);

    // GLFW 윈도우 생성
    GLFWwindow* window = glfwCreateWindow(800, 600, "GLFW Custom Shader", NULL, NULL);
    if (window == NULL) {
        glfwTerminate();
        return -1;
    }
    glfwMakeContextCurrent(window);

    // GLAD로 OpenGL 함수 포인터 초기화
    gladLoadGLLoader((GLADloadproc)glfwGetProcAddress);

    // OpenGL 설정
    glViewport(0, 0, 800, 600);

    // 루프
    while (!glfwWindowShouldClose(window)) {
        // 입력 이벤트 처리, 그리기 등의 코드
        // ...

        // Swap buffers 및 이벤트 polling
        glfwSwapBuffers(window);
        glfwPollEvents();
    }

    // GLFW 및 OpenGL 정리
    glfwTerminate();
    return 0;
}

사용자 정의 셰이더 로딩 및 컴파일링

사용자 정의 셰이더를 로딩하고 컴파일하기 위해 다음 함수를 사용할 수 있습니다. 아래 예제는 간단한 버텍스 셰이더와 프래그먼트 셰이더를 로딩하고 컴파일하는 코드를 보여줍니다.

#include <string>
#include <fstream>
#include <sstream>
#include <iostream>

// 사용자 정의 셰이더 로딩 및 컴파일 함수
unsigned int loadAndCompileShader(const char* shaderPath, GLenum shaderType) {
    std::string shaderCode;
    std::ifstream shaderFile;

    // 파일 읽기
    shaderFile.exceptions(std::ifstream::failbit | std::ifstream::badbit);
    try {
        shaderFile.open(shaderPath);
        std::stringstream shaderStream;
        shaderStream << shaderFile.rdbuf();
        shaderFile.close();
        shaderCode = shaderStream.str();
    }
    catch (std::ifstream::failure& e) {
        std::cout << "Shader 파일 읽기 오류: " << e.what() << std::endl;
    }

    const char* shaderCodeChar = shaderCode.c_str();
    unsigned int shader;

    // 셰이더 생성, 소스 연결, 컴파일
    shader = glCreateShader(shaderType);
    glShaderSource(shader, 1, &shaderCodeChar, NULL);
    glCompileShader(shader);

    // 컴파일 상태 확인
    int success;
    char infoLog[512];
    glGetShaderiv(shader, GL_COMPILE_STATUS, &success);
    if (!success) {
        glGetShaderInfoLog(shader, 512, NULL, infoLog);
        std::cout << "컴파일 오류: " << infoLog << std::endl;
    }

    return shader;
}

// 버텍스 셰이더 로딩 및 컴파일
unsigned int vertexShader = loadAndCompileShader("vertex_shader.glsl", GL_VERTEX_SHADER);

// 프래그먼트 셰이더 로딩 및 컴파일
unsigned int fragmentShader = loadAndCompileShader("fragment_shader.glsl", GL_FRAGMENT_SHADER);

셰이더 프로그램 생성 및 링크

로딩 및 컴파일한 사용자 정의 버텍스 및 프래그먼트 셰이더를 링크하여 셰이더 프로그램을 생성할 수 있습니다. 아래 예제는 셰이더 프로그램을 생성하고 링크하는 코드를 보여줍니다.

// 셰이더 프로그램 생성
unsigned int shaderProgram;
shaderProgram = glCreateProgram();

// 셰이더 프로그램에 버텍스 셰이더 및 프래그먼트 셰이더 링크
glAttachShader(shaderProgram, vertexShader);
glAttachShader(shaderProgram, fragmentShader);
glLinkProgram(shaderProgram);

// 링크 상태 확인
int success;
char infoLog[512];
glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success);
if (!success) {
    glGetProgramInfoLog(shaderProgram, 512, NULL, infoLog);
    std::cout << "링크 오류: " << infoLog << std::endl;
}

// 셰이더 프로그램 사용
glUseProgram(shaderProgram);

이제 GLFW를 사용하여 OpenGL에서 사용자 정의 셰이더를 처리하는 기본적인 방법을 살펴보았습니다. 사용자 정의 셰이더를 통해 그래픽스 파이프라인을 구성하고, 화면 출력을 자유롭게 조작할 수 있게 됩니다.

참고 문헌: