[Grapics] OpenGL (5)

suhan0304·2024년 7월 4일

Graphics - OpenGL

목록 보기
5/5
post-thumbnail

저번에 다뤘던 Uniform Variables를 사용해보자.


Uniform Variable

Unifrom Variable은 저번에도 다뤘지만 간단히 말해 vertex 별로 값을 설정해주는 것이 아니라, Shader 전역에 적용되는 값이라고 생각하면 된다. 주로 모든 vertex, 즉 객체 자체의 위치를 움직이거나, 회전, 또는 크기를 조절할 때 사용한다.

한 번 저번에 그렸던 삼각형을 움직여보자.

GLuint VAO, VBO, shader, uniformXMove;

bool direction = true;
float triOffset = 0.0f;
float triMaxOffset = 0.7f;
float triIncrement = 0.0005f;

// Vertex Shader
static const char* vShader = "											\n\
#version 330															\n\
																		\n\
layout(location = 0) in vec3 pos;										\n\
																		\n\
uniform float xMove;													\n\
																		\n\
void main()																\n\
{																		\n\
	gl_Position = vec4(0.4 * pos.x + xMove, 0.4 * pos.y, pos.z, 1.0);	\n\
}																		\n\
";

위와 같이 쉐이더 프로그램 내부에서 uniform 변수 xMove를 선언하고 Position에서 x값에 더해주도록 설정해주었다.


그 다음에 셰이더 컴파일 과정에서 shader에 포함되는 셰이더 프로그램에서 xMove라는 이름의 유니폼 변수의 위치를 가져온다.

void CompileShaders() {
	//  생략

	uniformXMove = glGetUniformLocation(shader, "xMove");
}

이제 셰이더 컴파일 과정에서 xMove라는 uniform 변수의 위치를 알았으니 이 값을 수정해주는 로직을 추가해주면 된다.


// Loop Until window Closed 
while (!glfwWindowShouldClose(mainWindow)) // 윈도우 창이 닫힐 때까지 반복 
{
	// Get + Handler user input events 
	glfwPollEvents(); // 클릭, 화면 이동, 리사이즈 등, 등 모든 이벤트를 감지

	if (direction) 
	{
		triOffset += triIncrement;
	}
	else 
	{
		triOffset -= triIncrement;
	}

	if (abs(triOffset) >= triMaxOffset) {
		direction = !direction;
	}

	// Clear Window 
	glClearColor(0.0f, 0.0f, 0.0f, 1.0f); // 특정 색(빨강)으로 지우기
	glClear(GL_COLOR_BUFFER_BIT); // 색 버퍼를 특정 색(빨강)으로 지우기

	glUseProgram(shader); // 생성한 셰이더 ID를 잡음 (셰이더가 여러개 일 때 구별해서 잡는데 사용)
	// 여기에 작성되는 것은 위에서 잡은 셰이더 프로그램으로 그려짐

	glUniform1f(uniformXMove, triOffset);

	glBindVertexArray(VAO); //VAO 바인드
	glDrawArrays(GL_TRIANGLES, 0, 3); // 0~3번째 점까지 사용해서 삼각형 그리기
	glBindVertexArray(0); // VAO 언바인드
		 
	glUseProgram(0); //잡은 셰이더를 해제

	// 화면에 보여지는 버퍼와 렌더링에 사용되는 버퍼를 교체
	glfwSwapBuffers(mainWindow); 

}

위 코드는 main 내부에서 윈도우 창을 그리는 과정이다. 이 때 주목해야할 코드가 바로 glUniform1f이다.

glUniform1f(uniformXMove, triOffset);

컴파일 과정에서 가져온 uniform 변수 uniformXMove의 변수에 triOffset 값을 설정해준다.

참고로 triOffset은 direction에 따라 triIncrement 값만큼 증감을 계속해서 반복하도록 구현했다.

if (direction) 
{
	triOffset += triIncrement;
}
else 
{
	triOffset -= triIncrement;
}

if (abs(triOffset) >= triMaxOffset) {
	direction = !direction;
}

이제 실행을 시켜보면 uniform 변수 xMove의 영향을 받아서 삼각형의 x좌표가 증가했다가 감소했다를 반복, 즉 좌우로 움직이면 된다.

잘 동작한다.

이처럼 모든 vertex에 대해 동일한 어떠한 기능을 수행할 때 uniform 변수를 만들어서 구현해낼 수 있다. 즉, uniform 변수는 별도로 수정해주지 않으면 다른 vertex가 새로 들어와도 동일하게 동작한다는 것이다.


profile
Be Honest, Be Harder, Be Stronger

0개의 댓글