#74
2022,2026 두 차례의 월드컵을 통해 메시의 큰 팬이 되었습니다.
이를 기념해 ThorVG 의 Drawing API 를 사용해 메시의 아르헨티나 국가대표 유니폼을 그려보기로 합니다.
[결과물]
[상세]
<아르헨티나 유니폼>
아르헨티나 유니폼의 형상과 특유의 하얀색~하늘색의 Gradient 를 구현했습니다.
` // --------------------------------------------------------------------- // Argentina Uniform // ---------------------------------------------------------------------
auto bg = tvg::Shape::gen();
bg->appendRect(0, 0, w, h);
bg->fill(250, 250, 250);
canvas->add(bg);
// Argentina sky-blue stripes
const uint8_t skyR = 120;
const uint8_t skyG = 205;
const uint8_t skyB = 255;
float stripe = w / 7.0f;
for (int i = 0; i < 7; i++) {
if (i % 2 == 0) continue;
auto rect = tvg::Shape::gen();
rect->appendRect(i * stripe, 0, stripe, h);
rect->fill(skyR, skyG, skyB);
canvas->add(rect);
}
float side = w * 0.18f;
float center = w * 0.08f;
tvg::Fill::ColorStop stops[4] = {
{0.0f, 100,190,245,255},
{0.25f,145,220,255,255},
{0.75f,145,220,255,255},
{1.0f,100,190,245,255}
};
auto stripe1 = tvg::Shape::gen();
stripe1->appendRect(w*0.08f, 0, side, h);
auto grad1 = tvg::LinearGradient::gen();
grad1->linear(
w*0.08f,
0,
w*0.08f + side,
0
);
grad1->colorStops(stops,5);
stripe1->fill(grad1);
canvas->add(stripe1);
auto stripe2 = tvg::Shape::gen();
stripe2->appendRect(w*0.46f, 0, center, h);
auto grad2 = tvg::LinearGradient::gen();
grad2->linear(
w*0.46f,
0,
w*0.46f + center,
0
);
grad2->colorStops(stops,5);
stripe2->fill(grad2);
canvas->add(stripe2);
auto stripe3 = tvg::Shape::gen();
stripe3->appendRect(w*0.74f, 0, side, h);
auto grad3 = tvg::LinearGradient::gen();
grad3->linear(
w*0.74f,
0,
w*0.74f + side,
0
);
grad3->colorStops(stops,5);
stripe3->fill(grad3);
canvas->add(stripe3);
// left shoulder
auto leftShoulder = tvg::Shape::gen();
leftShoulder->moveTo(0,0);
leftShoulder->lineTo(w*0.18f,0);
leftShoulder->lineTo(0,h*0.12f);
leftShoulder->close();
leftShoulder->fill(235,235,235);
canvas->add(leftShoulder);
// right shoulder
auto rightShoulder = tvg::Shape::gen();
rightShoulder->moveTo(w,0);
rightShoulder->lineTo(w,h*0.12f);
rightShoulder->lineTo(w*0.82f,0);
rightShoulder->close();
rightShoulder->fill(235,235,235);
canvas->add(rightShoulder);
// neck
auto neck = tvg::Shape::gen();
neck->appendRect(w*0.44f,0,w*0.12f,10);
neck->fill(30,30,30);
canvas->add(neck);`
<유니폼 효과>
유니폼 전체를 덮는 반투명한 세로 방향의 Gradient Overlay를 추가하여, 윗부분은 약간 밝고 아랫부분은 약간 어둡게 하여 입체감을 부여하고자 했습니다.
` // ---------------------------------------------------------- // Uniform Effect // ----------------------------------------------------------
auto overlay = tvg::Shape::gen();
overlay->appendRect(0,0,w,h);
auto shade = tvg::LinearGradient::gen();
shade->linear(0,0,0,h);
tvg::Fill::ColorStop s[3] = {
{0.0f,255,255,255,45},
{0.55f,255,255,255,0},
{1.0f,120,120,120,35}
};
shade->colorStops(s,3);
overlay->fill(shade);
canvas->add(overlay);`
<배지>
월드컵 우승팀을 상징하는 배지를 그려보았습니다. 원래는 월드컵 트로피 형상이어야 하는데 이게 디테일하게 그리기는 좀 어려워서 간단히 금색 배지로 갈음했습니다.
` // ---------------------------------------------------------- // Champion Badge // ----------------------------------------------------------
const float badgeW = 46;
const float badgeH = 62;
float badgeX = w * 0.5f - badgeW * 0.5f;
float badgeY = 40;
// Shadow
auto shadow = tvg::Shape::gen();
shadow->appendRect(
badgeX+2,
badgeY+2,
badgeW,
badgeH,
8,
8
);
shadow->fill(0,0,0,40);
canvas->add(shadow);
// Outer
auto badge = tvg::Shape::gen();
badge->appendRect(
badgeX,
badgeY,
badgeW,
badgeH,
8,
8
);
badge->fill(212,175,55);
canvas->add(badge);
// Inner
auto inner = tvg::Shape::gen();
inner->appendRect(
badgeX+5,
badgeY+5,
badgeW-10,
badgeH-10,
6,
6
);
inner->fill(245,220,90);
canvas->add(inner);
// White circle
auto circle = tvg::Shape::gen();
circle->appendCircle(
badgeX+badgeW/2,
badgeY+18,
5,
5
);
circle->fill(255,255,255);
canvas->add(circle);`
< Messi 10 >
메시의 이름과 백넘버를 그렸습니다. 글씨에 그림자 효과도 적용하여 조금 더 깊이감을 주었습니다.
`
//-----------------------------
// “Messi 10”
//-----------------------------
// Load font
if (!tvgexam::verify(tvg::Text::load(EXAMPLE_DIR "/font/DejaVuSans-Bold.ttf")))
return false;
//-----------------------------
// "messi"
//-----------------------------
auto name = tvg::Text::gen();
name->font("DejaVuSans-Bold");
name->size(60);
name->text("messi");
name->fill(0, 0, 0);
//-----------------------------
// "10"
//-----------------------------
auto number = tvg::Text::gen();
number->font("DejaVuSans-Bold");
number->size(100);
number->text("10");
number->fill(0, 0, 0);
// Measure Font Size
float x, y, nameW, nameH;
float nx, ny, numW, numH;
name->bounds(&x, &y, &nameW, &nameH);
number->bounds(&nx, &ny, &numW, &numH);
// Center Alignment
const float spacing = 45.0f;
float totalHeight = nameH + spacing + numH;
float startY = (h - totalHeight) * 0.5f;
float nameX = (w - nameW) * 0.5f - x;
float nameY = startY - y;
float numX = (w - numW) * 0.5f - nx;
float numY = startY + nameH + spacing - ny;
name->translate(nameX, nameY);
number->translate(numX, numY);
//-----------------------------
// "Messi" Shadow Efect
//-----------------------------
auto nameShadow = tvg::Text::gen();
nameShadow->font("DejaVuSans-Bold");
nameShadow->size(60);
nameShadow->text("messi");
nameShadow->fill(90,90,90);
nameShadow->translate(nameX + 2, nameY + 2);
//-----------------------------
// "10" Shadow Efect
//-----------------------------
auto numShadow = tvg::Text::gen();
numShadow->font("DejaVuSans-Bold");
numShadow->size(100);
numShadow->text("10");
numShadow->fill(90,90,90);
numShadow->translate(numX + 4, numY + 4);
canvas->add(nameShadow);
canvas->add(numShadow);
canvas->add(name);
canvas->add(number); `
댓글
Discussion 원문