* Computer Graphics Programming in OpenGL with C++ 책을 참고하였습니다.
* 책을 번역한 것이 아닌, 제가 독학 후 책을 참고하여 설명하는 게시물입니다. 따라서 책에 없는 부연 설명이 있기도 하며, 의역 또는 오역, 오개념이 있을 수 있습니다. 피드백은 댓글을 남겨주세요.
* 영어 용어를 최대한 한국어로 번역하지 않습니다. 처음부터 코드에서 사용되는, 또는 원서나 인터넷에서 사용되는 보편적 용어를 사용하여 개념을 잡는 것을 추천드립니다.
GLSL 코드의 컴파일은 C++ 런타임 중에 진행됩니다. 즉, 쉐이더 코드는 빌드 후에 컴파일이 시작되는 것입니다. 또한 GLSL 코드는 CPU가 아닌 GPU에서 실행되기 때문에, OS(운영체제)가 OpenGL 런타임 에러를 항상 잡을 수 있는 것은 아닙니다. 따라서 디버깅이 힘들고, 쉐이더에 문제가 생기더라도 이유를 알기 어렵죠.
이번 게시물에서는, 책에서 제공된 모듈을 공유하려고 합니다. 이 모듈은 GLSL 에러를 감지하고 알려주는 역할을 합니다.
[Program 2.3 Modules to Catch GLSL Errors]
void printShaderLog(GLuint shader) {
int len = 0;
int chWrittn = 0;
char* log;
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &len);
if (Len > 0) {
log = (char*)malloc(len);
glGetShaderInfoLog(shader, len, &chWrittn, log);
cout << "Shader Info Log: " << log << ends;
free(log);
}
}
void printProgramLog(int prog) {
int len = 0;
int chWrittn = 0;
char* log;
glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &len);
if (len > 0) {
log = (char*)malloc(len);
glGetProgramInfoLog(prog, len, &chWrittn, log);
cout << "Program Info Log: " << log << endl;
free(log);
}
}
bool checkOpenGLError() {
bool foundError = false;
int glErr = glGetError();
while (glErr != GL_NO_ERROR) {
cout << "glError: " << glErr << endl;
foundError = true;
glErr = glGetError();
}
return foundError;
}
이 코드는 지난 프로그램 2.2의 createShaderProgram() 함수 안에 위치하면 됩니다. 위 코드의 세 함수의 역할은 다음과 같습니다:
1. checkOpenGLError( )는 발생된 OpenGL의 에러 flag를 확인합니다.
2. printShaderLog( )는 GLSL의 컴파일이 실패할 경우 OpenGL의 로그(log)의 내용을 보여줍니다.
3. printProgramLog( )는 GLSL 링크(연결)에 실패할 경우 OpenGL의 로그의 내용을 보여줍니다.
이 모듈을 사용하려면 해당 함수들을 호출해 주어야겠죠? 에러 검출이 필요할 때마다 호출해서 사용하면 됩니다. 아래 코드는 같은 프로그램에서 사용된 예제입니다.
// main.cpp createShaderProgram()
glCompileShader(vShader);
checkOpenGLError();
glGetShaderiv(vShader, GL_COMPILE_STATUS, &vertCompiled);
if (vertCompiled != 1) {
cout << "vertex compilation failed" << endl;
printShaderLog(vShader);
}
glCompileShader(fShader);
checkOpenGLError();
glGetShaderiv(fShader, GL_COMPILE_STATUS, &fragCompiled);
if (fragCompiled != 1) {
cout << "fragment compilation failed" << endl;
printShaderLog(fShader);
}
GLuint vfProgram = glCreateProgram();
glAttachShader(vfProgram, vShader);
glAttachShader(vfProgram, fShader);
glLinkProgram(vfProgram);
checkOpenGLError();
glGetProgramiv(vfProgram, GL_LINK_STATUS, &linked);
if (linked != 1) {
cout << "linking failed" << endl;
}
이 모듈을 사용하는 것 외에도 어느 쉐이더 코드에 문제가 있는지 찾아내는 방법은 얼마든지 있습니다. 틀릴 수 없는 코드를 대체하여 결과를 지켜보는 방법도 이에 해당됩니다. 하지만, 이러한 모듈을 사용하면 시간을 훨씬 많이 절약할 수 있습니다.
모둘을 적용시킨 결과, 쉐이더 코드에서 오류가 발생하면 CLI에 오류에 대한 정보가 잘 출력됩니다.
'College Study > OpenGL' 카테고리의 다른 글
[그래픽스] 정점으로 개체 그리기, 애니메이팅, 모듈화 (0) | 2020.06.09 |
---|---|
[그래픽스] 파일에서 GLSL 소스코드 읽기 (0) | 2020.06.08 |
[그래픽스] Shader (쉐이더) (0) | 2020.06.04 |
[그래픽스] OpenGL 프로그램 개요 (1) | 2020.06.01 |
[선형대수학] 벡터 (Vector), 그래픽스 기초 (0) | 2020.06.01 |
댓글