Computer Graphics/OpenGL

OpenGL 정리 - 8. Texture 사용 과정, 다중 Texture, Mipmap

surkim 2024. 9. 12. 15:25

이번 포스팅에서는 OpenGL에서 텍스처를 사용하는 방법에 대해 더 자세히 설명하겠다.

텍스처는 3D 그래픽에서 물체의 표면에 이미지를 입혀 더욱 현실감 있는 렌더링을 가능하게 한다.

이 글에서는 텍스처의 사용 과정다중 텍스처, 그리고 Mipmap에 대해 알아보겠다.


텍스처 사용 과정

OpenGL에서 텍스처를 사용하는 과정은 다음과 같다:

 

1. 텍스처 객체를 생성하기 위해 glGenTextures를 사용한다.

이 함수는 텍스처 객체의 ID를 반환하며, 이 ID를 사용해 텍스처 작업을 수행한다.

glGenTextures(1, &m_texture);

 

 

2. 생성한 텍스처 객체를 GL_TEXTURE_2D로 바인딩하여 이후의 모든 텍스처 작업이 해당 텍스처에 적용되도록 한다.

glBindTexture(GL_TEXTURE_2D, m_texture);

 

 

3. 텍스처 좌표가 [0, 1] 범위를 넘을 경우의 처리 방식(래핑)과, 텍스처가 축소 및 확대될 때 필터링 방식을 설정한다.

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

 

 

4. 이미지 데이터를 텍스처에 업로드한다. glTexImage2D 함수는 텍스처의 크기, 포맷, 데이터 타입, 실제 이미지 데이터를 전달받아 GPU에 텍스처를 저장한다.

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);

 

 

5. 셰이더에서 텍스처를 사용하려면 uniform 변수를 통해 텍스처 유닛을 셰이더에 전달해야 한다. glUniform1i로 셰이더의 sampler2D 변수에 텍스처 유닛 번호(0번)를 설정한다.

glUniform1i(glGetUniformLocation(m_program->Get(), "texture1"), 0);

다중 텍스처 사용 과정 

1. 다중 텍스처를 사용하려면 각 텍스처를 로드하고, 텍스처 유닛에 각각 바인딩한 후 셰이더에 전달한다.

여러 텍스처 이미지를 로드하고 각각의 텍스처 객체를 생성한다.

auto image1 = Image::Load("container.jpg");
m_texture = Texture::CreateFromImage(image1.get());

auto image2 = Image::Load("awesomeface.png");
m_texture2 = Texture::CreateFromImage(image2.get());

 

 

2. 첫 번째 텍스처는 GL_TEXTURE0 유닛에, 두 번째 텍스처는 GL_TEXTURE1 유닛에 바인딩한다.

glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, m_texture->Get());

glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, m_texture2->Get());

 

 

3. 셰이더 프로그램에서 각각의 텍스처 유닛을 uniform 변수를 통해 전달한다. 첫 번째 텍스처는 0번 텍스처 유닛에, 두 번째 텍스처는 1번 텍스처 유닛에 할당한다.

m_program->Use();
glUniform1i(glGetUniformLocation(m_program->Get(), "tex"), 0);
glUniform1i(glGetUniformLocation(m_program->Get(), "tex2"), 1);

 

 

4. 셰이더 코드에서는 두 텍스처의 비율을 설정해 블렌딩할 수 있다. 아래 예시는 두 텍스처를 각각 80%, 20%로 블렌딩하여 출력한다.

#version 330 core
in vec2 texCoord;
out vec4 FragColor;

uniform sampler2D tex;
uniform sampler2D tex2;

void main() {
    FragColor = texture(tex, texCoord) * 0.8 + texture(tex2, texCoord) * 0.2;
}

Mipmap 사용

Mipmap은 텍스처의 크기를 줄인 여러 버전을 미리 생성하여, 화면에 적합한 크기의 텍스처를 선택해 사용함으로써 성능을 향상시키는 방법이다.

 

Mipmap을 자동으로 생성하기 위해 텍스처를 업로드한 후 glGenerateMipmap을 호출한다.

glGenerateMipmap(GL_TEXTURE_2D);

 

 

Mipmap 필터링을 설정하여, 텍스처가 작아질 때에도 부드러운 이미지를 제공한다.

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);