-
-
Save Reputeless/fe56139865e109a902e829218feb7794 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# include <Siv3D.hpp> // Siv3D v0.6.14 | |
// チュートリアル 41.3 | |
BlendState MakeBlendState() | |
{ | |
BlendState blendState = BlendState::Default2D; | |
blendState.srcAlpha = Blend::SrcAlpha; | |
blendState.dstAlpha = Blend::DestAlpha; | |
blendState.opAlpha = BlendOp::Max; | |
return blendState; | |
} | |
void UnpremultiplyAlpha(Image& image) | |
{ | |
for (auto& pixel : image) | |
{ | |
if (pixel.a) | |
{ | |
ColorF color = pixel; | |
color.r /= color.a; | |
color.g /= color.a; | |
color.b /= color.a; | |
pixel = color; | |
} | |
} | |
} | |
MultiPolygon createLogoPolygon() { | |
Bezier3 bezier(Vec2(230, 429), Vec2(404, 490), Vec2(573, 375), Vec2(573, 277)); | |
Bezier3 bezier2(Vec2(573, 277), Vec2(573, 194), Vec2(467, 141), Vec2(425, 244)); | |
Bezier3 bezier3(Vec2(401, 245), Vec2(456, 124), Vec2(626, 165), Vec2(626, 304)); | |
Bezier3 bezier4(Vec2(626, 304), Vec2(626, 440), Vec2(420, 530), Vec2(230, 429)); | |
auto moveBy = [](Bezier3& bezier, Vec2 v) { | |
bezier.p0 += v; | |
bezier.p1 += v; | |
bezier.p2 += v; | |
bezier.p3 += v; | |
}; | |
moveBy(bezier, Vec2(-400, -300)); | |
moveBy(bezier2, Vec2(-400, -300)); | |
moveBy(bezier3, Vec2(-400, -300)); | |
moveBy(bezier4, Vec2(-400, -300)); | |
auto pop_back = [](LineString points) { | |
points.pop_back(); | |
return points; | |
}; | |
Array<Vec2> points; | |
points.append(pop_back(bezier.getLineString())); | |
points.append(pop_back(bezier2.getLineString())); | |
points.append(pop_back(bezier3.getLineString())); | |
points.append(pop_back(bezier4.getLineString())); | |
MultiPolygon multiPolygon(2); | |
multiPolygon[0] = Polygon(points); | |
multiPolygon[0] = Geometry2D::Or(multiPolygon[0], Circle(49, -42, 50).asPolygon())[0]; | |
multiPolygon[1] = multiPolygon[0].rotated(180_deg); | |
return multiPolygon; | |
} | |
void Main() | |
{ | |
Window::Resize(1280, 720); | |
Scene::SetBackground(Palette::Black); | |
Font font(240, Typeface::Black); | |
String text = U"Siv3Dしぶすりーでぃー"; | |
struct PosAngleScaleColor | |
{ | |
Vec2 pos; | |
double angle; | |
double scale; | |
Color color; | |
}; | |
Array<PosAngleScaleColor> posAngleScaleColors{ | |
{ Vec2(400, 60),10_deg, 1, Palette::Lightskyblue },//s | |
{ Vec2(560, 120), 5_deg, 0.8, Palette::Lightskyblue },//i | |
{ Vec2(620, 160), -15_deg, 1, Palette::Lightskyblue },//v | |
{ Vec2(550, 300), 10_deg, 1, Color{ 255, 228, 0} },//3 | |
{ Vec2(700, 310), -10_deg, 1, Palette::Gold },//D | |
{ Vec2(380, 270), 5_deg, 0.3, Color{ 71, 185, 255 } },//し | |
{ Vec2(440, 280), 0, 0.3, Color{ 71, 185, 255 } },//ぶ | |
{ Vec2(470, 500), 10_deg, 0.3, Color{ 255, 199, 0 } },//す | |
{ Vec2(550, 510), 5_deg, 0.3, Color{ 255, 199, 0 } },//り | |
{ Vec2(620, 530), 0, 0.3, Color{ 255, 199, 0 } },//ー | |
{ Vec2(700, 510), -5_deg, 0.3, Color{ 255, 199, 0 } },//で | |
{ Vec2(780, 520), -10_deg, 0.25, Color{ 255, 199, 0 } },//ぃ | |
{ Vec2(840, 500), -20_deg, 0.3, Color{ 255, 199, 0 } },//ー | |
}; | |
struct CharaData | |
{ | |
MultiPolygon polygon; | |
Color color{}; | |
}; | |
Array<CharaData> charas; | |
for (auto [i, t] : Indexed(text)) { | |
CharaData c; | |
c.polygon = font.renderPolygon(t).polygons; | |
for (auto& p : c.polygon) { | |
p = p.calculateRoundBuffer(4).scale(posAngleScaleColors[i].scale).rotate(posAngleScaleColors[i].angle).moveBy(posAngleScaleColors[i].pos); | |
} | |
c.color = posAngleScaleColors[i].color; | |
charas.push_back(c); | |
} | |
charas.push_back({ createLogoPolygon().scale(0.3).rotate(25_deg).moveBy(436,420),Color{ 36, 168, 249 } }); | |
charas.push_back({ MultiPolygon{Circle(837,220,50).asPolygon(36)},Palette::Orchid }); | |
charas.push_back({ MultiPolygon{Polygon{{893,360},{924,309},{916,215},{990,300},{1011,400},{957,482}, {899,445} }}, Palette::Lightgreen }); | |
charas.push_back({ MultiPolygon{Shape2D::Plus(30,18,{877,305},15_deg) }, Palette::Gainsboro }); | |
charas.push_back({ MultiPolygon{Shape2D::Plus(30,18,{344,352},-15_deg) }, Palette::Gainsboro }); | |
MultiPolygon bufferedPolygon; | |
for (auto& chara : charas) { | |
for (auto& p : chara.polygon) { | |
bufferedPolygon.push_back(p.calculateRoundBuffer(20)); | |
} | |
} | |
MultiPolygon bufferedPolygonConnected; | |
for (auto& p : bufferedPolygon) { | |
bufferedPolygonConnected = Geometry2D::Or(bufferedPolygonConnected, p); | |
} | |
for (auto& p : bufferedPolygonConnected) { | |
p = Polygon(p.outer()); | |
} | |
MSRenderTexture renderTexture(1280, 720, Color{ 0, 0 }); | |
{ | |
ScopedRenderTarget2D target(renderTexture); | |
ScopedRenderStates2D blend{ MakeBlendState() }; | |
{ | |
Transformer2D t(Mat3x2::Translate(10, 20)); | |
bufferedPolygonConnected.draw(Palette::Steelblue); | |
} | |
bufferedPolygonConnected.draw(Palette::White); | |
for (auto& chara : charas) { | |
for (auto& p : chara.polygon) { | |
p.draw(chara.color); | |
} | |
} | |
Circle(837, 220, 40).draw(Palette::Plum); | |
Shape2D::Star(23, { 837,220 }, 15_deg).asPolygon().calculateRoundBuffer(6).draw(Color{ 255, 255, 135 }); | |
Triangle tailPattern{ {0,-30},{10,0},{-10,0} }; | |
tailPattern.rotatedAt({}, 110_deg).movedBy(924, 309).draw(Palette::Whitesmoke); | |
tailPattern.scaledAt({}, 0.7).rotatedAt({}, 80_deg).movedBy(922, 259).draw(Palette::Whitesmoke); | |
tailPattern.scaledAt({}, 0.8).rotatedAt({}, 130_deg).movedBy(902, 347).draw(Palette::Whitesmoke); | |
Polygon{ {893,360},{924,309},{916,215},{934,314} }.draw(Palette::Dimgray); | |
Polygon{ {893,360},{957,482}, {899,445} }.draw(Palette::Darkseagreen.withAlpha(128)); | |
} | |
Graphics2D::Flush(); | |
renderTexture.resolve(); | |
Image image; | |
renderTexture.readAsImage(image); | |
UnpremultiplyAlpha(image); | |
const Texture texture{ image }; | |
Scene::SetBackground(ColorF{ 0.96, 0.98, 1.0 }); | |
while (System::Update()) | |
{ | |
for (int32 y = 0; y < (Scene::Height() / 80); ++y) | |
{ | |
for (int32 x = 0; x < (Scene::Width() / 80); ++x) | |
{ | |
if (IsEven(y + x)) | |
{ | |
Rect{ (x * 80), (y * 80), 80 }.draw(ColorF{ 0.8, 0.82, 0.84 }); | |
} | |
} | |
} | |
texture.draw(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment