인프런 영문 브랜드 로고
인프런 영문 브랜드 로고

인프런 커뮤니티 질문&답변

원덕희님의 프로필 이미지
원덕희

작성한 질문수

게임 개발자를 위한 3D 그래픽스, 쉐이더, OpenGL (2) - 프로그래머블 파이프라인, 기하학 기초, 삼각형 출력

hello shader 프로그램 실행이 안됩니다.

해결된 질문

작성

·

99

·

수정됨

0

강사님 제공된 코드를 실행을 해봤을 때 삼각형이 보이지 않고 빈 화면만 나오는 문제가 있습니다.

 

따로 glGenBuffers를 이용해서 버퍼를 생성하고 데이터를 바인딩을 했을 때에는 삼각형이 나오는 것을 확인을 했습니다.

 

이렇게 해결을 하는 것이 맞는지에 대해서 궁금합니다.

 

혹시 버퍼를 생성 하지 않고 진행을 하는 방법이 있는지 궁금합니다.

 

 

 

답변 1

0

안녕하세요.

괜찮으시면, 사용하신 컴퓨터 환경을 알려주실 수 있을지요.

말씀하신 상황이 발생했다면, 그래픽 카드 제조사에 리포트를 해야 할 것 같습니다.

그래픽 카드의 모델과, 디바이스 드라이버 버전, OpenGL 드라이버 버전 정도를 알려주시면, 해당 제조사에 버그 리포트 하고, 문제점을 파악해 보겠습니다.

감사합니다.

 

P.S: 혹시 glFlush() 나, glFinish() 함수가 빠져있다면, glDraw() 함수 이후에 마지막 부분에 glFinish()를 추가해서 해결하는 경우도 있습니다만, 지금 말씀 하신 증상으로는 그 문제도 아닌 것 같긴 합니다..

원덕희님의 프로필 이미지
원덕희
질문자

선생님 2019년도 맥북 프로 입니다.
OpenGL은 vcpkg로 설치를 진행을 했습니다.

=> 버전은 2022년12월4일에 배포된 버전인 3을 사용하고 있습니다.

 

현재 동작이 되는 코드는 다음과 같이 했을 때 동작을 하는 것을 확인 했습니다.

 

code

#include <iostream>

#include <GL/glew.h>
#include <GLFW/glfw3.h>

#include <glm/glm.hpp>

/** vertex shader source */
const char *vertexShaderSource = "#version 330 core \n"
                                 "in vec4 vertexPos; \n"
                                 "void main() { \n"
                                 "gl_Position = vertexPos; \n"
                                 "} \0";

/** fragment shader source */
const char *fragmentShaderSource = "#version 330 core \n"
                                   "out vec4 FragColor; \n"
                                   "void main(){ \n"
                                   "FragColor = vec4(1.0f, 0.0f, 0.0f, 1.0f); \n"
                                   "} \0";

/** vertex point coordinate */
GLfloat vertexPos[] = {
        -0.5F, -0.5F, 0.0F, 1.0F,
        +0.5F, -0.5F, 0.0F, 1.0F,
        -0.5F, +0.5F, 0.0F, 1.0F
};


/** event handler */
/** refresh handler */
void refreshHandler(GLFWwindow *window);

/** keyboard event handler */
void keyboardHandler(GLFWwindow *window, int key, int scancode, int action, int mods);

/** vertex program Initialized */
void initFunc(void);

/** draw shader source */
void drawFunc(void);

/** window size const set */
const unsigned int WIDTH = 800, HEIGHT = 600;

const unsigned int WIN_X = 100; // window position in pixels, (X, Y)
const unsigned int WIN_Y = 100;

GLuint VB0, VAO;


/** shader program ID */
GLuint shaderProgram;
/** vertex shader program ID */
GLuint vertexShader;
/** fragment shader program ID */
GLuint fragmentShader;


int main(int argc, char **argv) {

    /** GLFW Window variable */
    GLFWwindow *window = nullptr;

    /** glfw Initialized */
    if (glfwInit() == GLFW_FALSE) {
        std::cout << "GLFW Initialized Failed..." << std::endl;
        return -1;
    }

    /** OpenGL Version Hit -> glfw */
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
    glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
    glfwWindowHint(GLFW_RESIZABLE, GL_TRUE);

    /** create window */
    window = glfwCreateWindow(WIDTH, HEIGHT, "Hello Vertex", NULL, NULL);
    /** window position setting (x, y)*/
    glfwSetWindowPos(window, WIN_X, WIN_Y);

    /** create window check */
    if (window == nullptr) {
        std::cout << "Create window failed ..." << std::endl;
        glfwTerminate();
        return -1;
    }

    /** glfw create window context */
    glfwMakeContextCurrent(window);

    glewExperimental = GL_TRUE;

    /** glew Initialized */
    if (glewInit() != GLEW_OK) {
        std::cout << "OpenGL extension GLEW Initialized Failed..." << std::endl;
        glfwTerminate();
        return -1;
    }

    /** glfw Event Handler Setting */
    /** keyboard event handler registration */
    glfwSetKeyCallback(window, keyboardHandler);
    /** refresh event handler registration */
    glfwSetWindowRefreshCallback(window, refreshHandler);

    /** back ground color setting -> RGBA */
    glClearColor(0.5F, 0.5F, 0.5F, 1.0F);
    /** vertex array create and get vertex array ID */
    glGenVertexArrays(1, &VAO);
    /** create buffer and get buffer ID */
    glGenBuffers(1, &VB0);

    glBindVertexArray(VAO);
    glBindBuffer(GL_ARRAY_BUFFER, VB0);
    /** shader Initialized */
    initFunc();

    /** window loop */
    while (!glfwWindowShouldClose(window)) {
        /** event Listener */
        glfwPollEvents();
        /** frame buffer setting */
//        glClear(GL_COLOR_BUFFER_BIT);
        /** draw triangle */
        drawFunc();
        /** window frame buffer swap */
        glfwSwapBuffers(window);
    }
    /** using buffer remove */
    glDeleteVertexArrays(1, &VAO);
    glDeleteBuffers(1, &VB0);
    /** shader .obj file delete */
    glDeleteShader(vertexShader);
    glDeleteShader(fragmentShader);
    /** delete shader program */
    glDeleteProgram(shaderProgram);
    /** glfw terminate */
    glfwTerminate();
    return 0;
}

/** refresh handler */
void refreshHandler(GLFWwindow *window) {
    /** draw image */
    drawFunc();
    /** swap fraem buffer */
    glfwSwapBuffers(window);
}

/** keyboard event handler */
void keyboardHandler(GLFWwindow *window, int key, int scancode, int action, int mods) {
    switch (key) {
        case GLFW_KEY_ESCAPE:
            if (action == GLFW_PRESS) {
                glfwSetWindowShouldClose(window, GLFW_TRUE);
            }
            break;
    }
}


/** vertex program Initialized -> create shader and shader program */
void initFunc(void) {
    /** check log variable */
    int status;
    char log[1024] = {0,};
    /** vertex shader create */
    vertexShader = glCreateShader(GL_VERTEX_SHADER);
    /** vertex shader source set shader source */
    glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);
    /** vertex shader source code compile -> compile to get .OBJ */
    glCompileShader(vertexShader);
    /** check shader compile error */
    glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &status);
    std::cout << "vertex compile status : " << status << std::endl;
    if (!status) {
        glGetShaderInfoLog(vertexShader, 1024, NULL, log);
        std::cout << "vertex shader compile error - " << log << std::endl;
    }

    /** fragment shader create */
    fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
    /** fragment shader source set shader source */
    glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);
    /** fragment shader source code compile -> compile to get .OBJ */
    glCompileShader(fragmentShader);
    /** check shader compile error */
    glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &status);
    std::cout << "fragment compile status : " << status << std::endl;
    if (!status) {
        glGetShaderInfoLog(fragmentShader, 1024, NULL, log);
        std::cout << "vertex shader compile error - " << log << std::endl;
    }

    /** shader program create */
    shaderProgram = glCreateProgram();
    /** vertex shader and fragment shader attach */
    glAttachShader(shaderProgram, vertexShader);
    glAttachShader(shaderProgram, fragmentShader);
    /** link program -> link to get .EXE */
    glLinkProgram(shaderProgram);

    /** program link check */
    glGetProgramiv(shaderProgram, GL_LINK_STATUS, &status);
    std::cout << "link status " << status << std::endl;
    if (!status) {
        glGetProgramInfoLog(shaderProgram, 1024, NULL, log);
        std::cout << "shader program linked failed -> " << log << std::endl;
    }

    /** shader program validated */
    glValidateProgram(shaderProgram);
    /** program link check */
    glGetProgramiv(shaderProgram, GL_VALIDATE_STATUS, &status);
    std::cout << "link status " << status << std::endl;
    if (!status) {
        glGetProgramInfoLog(shaderProgram, 1024, NULL, log);
        std::cout << "shader program linked failed -> " << log << std::endl;
    }

    /** using shader program */
    glUseProgram(shaderProgram);

}

/** draw shader source */
void drawFunc(void) {
    /** OpenGL FrameBuffer Clear */
    /** COLOR Buffer clear */
    glClear(GL_COLOR_BUFFER_BIT);


//    glBufferData(GL_ARRAY_BUFFER, sizeof(vertexPos), vertexPos, GL_DYNAMIC_DRAW);

    /** get attribute variable get -> input setting */
    GLint locationAttribute = glGetAttribLocation(shaderProgram, "vertexPos");
    /** setting shader source variable */
    glEnableVertexAttribArray(locationAttribute);
    /** get vertex source variable get */
    glVertexAttribPointer(locationAttribute, 4, GL_FLOAT, GL_FALSE, 0, vertexPos);

    /** draw a triangle */
    glDrawArrays(GL_TRIANGLES, 0, 3);

    /** frame buffer change and wait all shader program done */
    glFinish();

}

 

cmake

cmake_minimum_required(VERSION 3.27)

project(chapter0201HelloShaderProgram LANGUAGES CXX VERSION 0.0.1)

message("chapter02-01 hello shader program GLSL")

find_package(OpenGL REQUIRED)
find_package(glfw3 REQUIRED CONFIG)
find_package(GLEW REQUIRED CONFIG)
find_package(glm REQUIRED CONFIG)


add_executable(chapter0201HelloShaderProgram)

target_sources(chapter0201HelloShaderProgram PRIVATE
        main.cpp)

target_link_libraries(chapter0201HelloShaderProgram LINK_PRIVATE
        OpenGL::GL
        glfw
        GLEW::GLEW
        glm::glm

)

 

 

원덕희님의 프로필 이미지
원덕희
질문자

혹시 여기서 glGenVertexArray, glGenBuffer 가 무엇인지 알 수 있을까요?

 

관련된 자료를 찾다가 코드들이 항상 사용을 하길래 추가를 했더니 동작을 하는 것을 봐서 vertexarray에 대한 생성 및 c코드에서 넘겨 받는 값을 임시 저장을 하는데 사용이 되는 것 같은데 정확히 어떤 역할인지 궁금해서 문의 드립니다.

Mac 일 줄은 몰랐습니다.

Mac 쪽은 2018년 이후인가, 그 이후부터는 OpenGL 관련된 기능들을 deprecate 시켜서, 더 이상 지원하지 않습니다. 경우에 따라서는 오동작하는 상황이 나올 수 있을 겁니다.

glGenBuffers 등의 함수는 이 강의에서 설명하고 있습니다만, 조금 더 진행해야 설명이 나올 겁니다.

감사합니다.

원덕희님의 프로필 이미지
원덕희
질문자

네 감사합니다

윈도우 환경에서 확인을 해보도록 하겠습니다.

원덕희님의 프로필 이미지
원덕희

작성한 질문수

질문하기