Scientia Conditorium

[OpenGL 008] glfw 키 2개 입력 방법 및 glfwSwapInterval 본문

프로그래밍/컴퓨터 그래픽스

[OpenGL 008] glfw 키 2개 입력 방법 및 glfwSwapInterval

크썸 2025. 2. 15. 03:34

이전 글 : https://molonlabe.tistory.com/130

 

[OpenGL 007] 쉐이더 파일 생성 및 프로그램 수정

이전글 : https://molonlabe.tistory.com/124 [OpenGL 006] 그래픽스 파이프 라인 및 간단한 쉐이더 프로그램이전글 : https://molonlabe.tistory.com/123 [OpenGL 005] Keyboard Callback 배경 색상 바꾸기이전글 : https://molonlabe

molonlabe.tistory.com


glfw는 더블 버퍼링과 V-sync 설정이 기본으로 설정되어 있습니다. 물론 이 설정들을 끄거나 바꿀 수 있습니다. 이 포스팅에서는 키보드 입력을 통해 V-sync 옵션을 끄고 키는 방법에 대해 다뤄보겠습니다.

 

 

 

glfwSwapInterval ( int interval )

이 함수는 OpenGL이나 OpenGLES context에 대한 교체 간격을 설정합니다. 즉, glfwSwapBuffers() 가 호출된 시간부터 버퍼를 교체하고 반환하기 전에 기다려야 하는 화면 업데이트 수를 말합니다. 이를 수직 동기화(Verticla synchronization), 단순하게 V-sync(브이 싱크) 라고도 합니다. glfw에서 별다른 설정을 건드리지 않았다면 기본적으로 60 ~70 FPS 정도에 맞추어져 있는 것을 알 수 있습니다. 따라서 이 함수를 이용하여 interval, 교체 간격을 없애면 GPU에서 가능한 많은 화면 업데이트를 진행할 것입니다. 사용 방법은 단순하게 glfwSwapInterval(0) 으로 V-sync를 끄거나 glfwSwapInterval(1)로 V-sync 기능을 킬 수 있습니다.

이 함수에서 대한 자세한 설명은 공식 문서를 참조하시기 바랍니다.

 

 

glfw keycallback 2개 입력

이전 포스팅에서 glfw 키보드 콜백을 구현했습니다. 만약 이전 포스팅을 못 보신 분이라면 다음 글을 참조하시길 바라겠습니다. 여기서는 최소한 키보드 콜백 함수는 구현되었다는 전제 하에 진행하겠습니다.

가장 단순한 방법으로는 키보드 콜백 함수의 mods와 action을 활용하는 방법입니다. 여기서 mods 는 shift, ctrl, alt, windows 키 등을 의미하며 action은 press, release, repeat 을 의미합니다. 따라서 Ctrl + Shift + 'C' 키를 입력 받았을 때 V-sync 설정을 끄겠다라고 한다면 다음과 같이 구현할 수 있습니다.

// Renderer.cpp
// glfw 키보드 콜백 함수
// shift 와 ctrl 키 활용 방법

void Renderer::keyFunc(GLFWwindow* window, int key, int scancode, int action, int mods)
{
	switch (key)
	{
	case GLFW_KEY_C:	// 키보드 'C' 키를 입력 받은 상태에서
	{
		static bool VSyncOn = true; // 기본적으로 glfw Vsync 옵션은 활성화 상태
        
        	// Shift 키와 Ctrl 키를 눌렀다면(Press)
		if ((mods == (GLFW_MOD_SHIFT | GLFW_MOD_CONTROL)) && (action == GLFW_PRESS))
		{
			if (VSyncOn)
			{
				glfwSwapInterval(0); // V-Sync off
				VSyncOn = false;
			}
			else
			{
				glfwSwapInterval(1); // V-Sync on
				VSyncOn = true;
			}
		}
		break;
	}
	default:
	{
		break;
	}
	}
}

 

그러나 위 방식은 shift와 ctrl 키만 활용할 수 있다는 단점이 있습니다. 따라서 키보드 콜백 방식을 사용했을 때 여러 키보드 입력을 받는 상태를 구현하고 싶다면 모든 키 상태값을 저장하고 이를 활용할 수 있습니다.

// glfw 키보드 콜백 함수
// 키보드 콜백 함수에서 여러 키를 동시에 입력받을 경우

bool keyStates[GLFW_KEY_LAST]{}; // 모든 키 상태값 저장

void Renderer::keyFunc(GLFWwindow* window, int key, int scancode, int action, int mods)
{
	if (key == GLFW_KEY_UNKNOWN)
	{
		return;
	}

	if (action == GLFW_PRESS)
	{
		keyStates[key] = true;	// 입력받은 key 값이 눌렸다면 true로 상태 변경
	}
	else if (action == GLFW_RELEASE)
	{
		keyStates[key] = false;	// 키보드에서 뗀 상태라면 key 값을 false로 변경
	}

	// 'A'와 'B'가 동시에 눌린 경우 확인
	if (keyStates[GLFW_KEY_A] && keyStates[GLFW_KEY_B])
	{
		glfwSwapInterval(0);
	}	
}

 

이 방식의 핵심은 모든 키 상태값을 저장할 수 있는 변수가 필요하다는 것입니다. 만약 나는 모든 키 상태값을 저장하지 않고 단순하게 'A' 키와 'B' 키를 같이 눌렀을 때 동작하게 하고 싶다면 glfwGetKey() 함수를 활용할 수 있습니다.

void Renderer::keyFunc(GLFWwindow* window, int key, int scancode, int action, int mods)
{
	if ((glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS) &&
		(glfwGetKey(window, GLFW_KEY_B) == GLFW_PRESS))
	{
		glfwSwapInterval(0); // V-Sync off
	}
}

 

glfwGetKey() 함수는 특정 키의 현재 상태를 확인할 수 있는 기능입니다. 엄밀히 따지자면 현재 상태라기 보다는 지정된 키에 저장된 마지막 상태값을 가져오는 것입니다. 반환되는 값은 GLFW_PRESS 또는 GLFW_RELEASE 만 반환됩니다. GLFW_PRESS와 GLFW_RELEASE 의 define 정의값은 각각 1과 0입니다. 즉, 내가 확인하고자 하는 특정 키 값이 누르고 있는 상태라면 GLFW_PRESS(1)을 반환하고 그렇지 않다면 GLFW_RELEASE(0) 값을 반환합니다. 이 함수를 활용하면 2개의 키가 아니라 3개, 4개 이상의 키를 한꺼번에 눌렀을 때 특정 동작을 하도록 구현할 수 있습니다.