DirectX11

[DX11] UV좌표를 활용한 Text 렌더링

yeoul0714 2025. 3. 19. 19:12

우리는 UV Mapping을 통해서 알파벳을 Rendering하는 것이 가능하다.

https://lucide.github.io/Font-Atlas-Generator/

 

Font Atlas Generator

 

lucide.github.io

 

 

그렇다면 이 텍스처를 이용해서 어떻게 화면에 원하는 영문을 띄울 수 있을까?

 

기본적인 아이디어는 바로 ASCII코드입니다. 

 

상단의 Font Atlas를 보면 영문자가 있는데 A의 경우 65번쨰 칸에 위치합니다. (4행/1열)

 

그런데 놀랍게도 A의 ASCII코드에서 정수 65로 대응이됩니다. (그렇게 만들어진 Atlas)

 

그렇다면 문자의 ASCII코드를 통해서 Font Atlas의 uv좌표를 정확히 계산해낸다면 

 

mapping이 가능할 것입니다.

void UTextComponent::CreateBufferForText(std::wstring text)
{
    SetRelativeLocationY(3.f);
    //isBill = true;

    float gap = 1.0f / 16.0f;
    size_t baseIndex = 0;
    vertices.clear();  // 기존 vertices 초기화
    indices.clear();   // 기존 indices 초기화

    float xOffset = text.size() * gap; // 텍스트의 x축 위치를 조정하기 위한 오프셋
    float yOffset = 0.0f; // 텍스트의 y축 위치를 고정

    for (size_t i = 0; i < text.size(); ++i) {
        // 각 문자의 아스키 코드 값 구하기
        wchar_t character = text[i];
        int charCode = (int)character;  // 아스키 코드 값

        // 해당 문자의 UV 좌표 계산
        float u = (charCode % 16) * (1.0f / 16.0f); // u 좌표 (16x16 그리드)
        float v = (charCode / 16) * (1.0f / 16.0f); // v 좌표 (16x16 그리드)

        // 각 문자에 대한 버텍스 계산 (사각형을 그리기 위한 4개 버텍스)
        vertices.push_back({ xOffset + 1.f,  1.f + yOffset, 0.f, 1.f, 0.f, 0.f, 1.f, u + gap, v }); // 우상단
        vertices.push_back({ xOffset + 1.f, -1.f + yOffset, 0.f, 0.f, 1.f, 0.f, 1.f, u + gap,v + gap }); // 우하단
        vertices.push_back({ xOffset - 1.f, -1.f + yOffset, 0.f, 0.f, 0.f, 1.f, 1.f, u, v + gap });     // 좌하단
        vertices.push_back({ xOffset - 1.f,  1.f + yOffset, 0.f, 1.f, 1.f, 0.f, 1.f, u, v });     // 좌상단

        // 인덱스 계산 (사각형을 그리기 위한 인덱스)
        indices.push_back(baseIndex + 3);
        indices.push_back(baseIndex + 0);
        indices.push_back(baseIndex + 1);
        indices.push_back(baseIndex + 3);
        indices.push_back(baseIndex + 1);
        indices.push_back(baseIndex + 2);

        // xOffset을 증가시켜서 각 문자 간격을 조정
        xOffset += 1.0f;

        // 다음 문자의 시작 인덱스를 갱신
        baseIndex += 4;
    }

}

 

 

코드에 대해 간략히 설명을 하자면 

 

gap : 한칸의 길이를 알기 위해서 1을 16으로 나눴다 (16은 한줄에 있는 문자의 수)

 

xOffset : 문자 하나의 정점 4개를 전부 만든뒤 다음 글자를 쓰기위해 offset만큼 x+ 방향으로 이동 

 

인덱스 버퍼역시 baseIndex의 값을 늘려주며 자동으로 생성되도록 하였습니다. 

uv 좌표
Font Atlas를 이용한 Text Rendering 사진