
저번에 다뤘던 Uniform Variables를 사용해보자.
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가 새로 들어와도 동일하게 동작한다는 것이다.