OpenGL 쉐이더 프로그래밍 - 디버깅 기초

타입·2025년 7월 22일

컴퓨터 그래픽스

목록 보기
7/24

GLSL 디버그 함수

  • 문제가 되는 fragment shader 코드
#version 330 core

in vec3 vColor; // vec4 -> vec3 타입 매칭 오류
out vec4 FragColor;

void main(void) {
	FragColor = vColor; // vec3 -> vec4 타입 매칭 오류
}
  • glGetShaderiv()
    pname으로 GL_COMPILE_STATUS를 전달하면 컴파일 결과를 파라미터로 반환 (성공 시 1)
  • glGetShaderInfoLog()
    컴파일 에러 메시지 반환
  • glGetProgramiv()
    프로그램의 링크/유효성 결과를 반환
  • glGetProgramInfoLog()
    링크/유효성 실패 메시지 반환
  • glValidateProgram()
    추가적인 유효성 검증
void initFunc(void) {
	const char* vertSource = loadFile( vertFileName );
	const char* fragSource = loadFile( fragFileName );
	char buf[1024]; // mesg buffer
	GLint status; // for glGetShaderiv()
    
	// vert: vertex shader
	vert = glCreateShader(GL_VERTEX_SHADER);
	glShaderSource(vert, 1, &vertSource, NULL);
	glCompileShader(vert); // compile to get .OBJ
	glGetShaderiv(vert, GL_COMPILE_STATUS, &status); // status에 컴파일 결과 저장
	printf("vert compile status = %s\n", (status == GL_TRUE) ? "true" : "false");
	glGetShaderInfoLog(vert, sizeof(buf), NULL, buf); // buf에 컴파일 실패 이유를 저장
	printf("vert log = [%s]\n", buf);
    
	// frag: fragment shader
	frag = glCreateShader(GL_FRAGMENT_SHADER);
	glShaderSource(frag, 1, &fragSource, NULL);
	glCompileShader(frag); // compile to get .OBJ
	glGetShaderiv(frag, GL_COMPILE_STATUS, &status); // 마찬가지로 컴파일 결과 저장
	printf("frag compile status = %s\n", (status == GL_TRUE) ? "true" : "false");
	glGetShaderInfoLog(frag, sizeof(buf), NULL, buf);
	printf("frag log = [%s]\n", buf);
    
	// prog: program
	prog = glCreateProgram();
	glAttachShader(prog, vert);
	glAttachShader(prog, frag);
	glLinkProgram(prog); // link to get .EXE
	glGetProgramiv(prog, GL_LINK_STATUS, &status); // 프로그램의 링크 결과를 반환
	printf("prog link status = %s\n", (status == GL_TRUE) ? "true" : "false");
	glGetProgramInfoLog(prog, sizeof(buf), NULL, buf);
	printf("link log = [%s]\n", buf);
	glValidateProgram(prog); // 유효성 검사 과정에서 warning 출력
	glGetProgramiv(prog, GL_VALIDATE_STATUS, &status); // 유효성 검사 결과를 반환
	printf("prog validate status = %s\n", (status == GL_TRUE) ? "true" : "false");
	glGetProgramInfoLog(prog, sizeof(buf), NULL, buf);
	printf("validate log = [%s]\n", buf);
	fflush(stdout);
    
	// execute it!
	glUseProgram(prog);
    
	// done
	free( (void*)vertSource );
	free( (void*)fragSource );
}
  • 에러 발생 로그
    fragment shader 컴파일 중 문제 발생
    이유: 서로 호환되지 않는 자료형을 assign 하려함
    0(7) -> 7번째 줄에서 에러 발생
vert compile status = true
vert log = []
frag compile status = false
frag log = [0(7) : error C1035: assignment of incompatible types
]
prog link status = false
link log = [Fragment info
-------------
0(7) : error C1035: assignment of incompatible types
(0) : error C2003: incompatible options for link
]
prog validate status = false
validate log = []

OpenGL 함수의 디버깅

OpenGL 에러 처리 방법

  • 전통적인 error flag 설정 방식
    OpenGL 드라이버 내부에 error flag 변수가 있음
    GLint errorFlag = GL_NO_ERROR;

  • 에러 세팅
    glClear(0xFFFF); // 허용되지 않은 값을 설정
    GL_INVALID_VALUE 에러 발생

  • 에러 발생 여부 체크
    • glGetError();
      error flag 값을 반환하고, 플래그 값은 GL_NO_ERROR로 초기화

OpenGL Debug Output

  • OpenGL Debug Extension
    GL_KHR_debug

  • Event-Driven Model
    OpenGL 에러 발생 시 이벤트 발생
    이벤트 핸들러에서 콜백 함수 호출

  • glEnable()/glDisable()
    OpenGL의 특정 기능을 On/Off

  • glDebugMessageControl()
    어느 디버그 이벤트를 활성화 할지 설정 (source/type/severity)

  • glDebugMessageCallback()
    디버그 메시지 콜백 함수 등록

void DebugLog(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length,
              const GLchar* message, const GLvoid* userParam) {
	printf("Type: %#x; Source: %#x; ID: %d; Severity: %#x\n", type, source, id, severity);
	printf("Message: %s\n", message );
	fflush(stdout);
}

int main(int argc, char* argv[]) {
	...
    
	glewInit();
    
	// register debug callback
	glEnable( GL_DEBUG_OUTPUT ); // Debug Output 활성화
	glEnable( GL_DEBUG_OUTPUT_SYNCHRONOUS ); // 에러 메시지가 즉시 나오도록 설정
    // GL_DONT_CARE로 모든 에러 메시지를 받도록 설정
	glDebugMessageControl( GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, NULL, GL_TRUE );
	glDebugMessageCallback( DebugLog, NULL ); // 콜백 함수 등록
    
    ...
}
  • 에러 메시지 출력
    glClear(0xFFFF)로 인해 GL_INVALID_VALUE 에러 발생 확인
Type: 0x824c; Source: 0x8246; ID: 1281; Severity: 0x9146
Message: GL_INVALID_VALUE error generated. Invalid clear bits.
profile
언리얼 프로그래머

0개의 댓글