差分
このページの2つのバージョン間の差分を表示します。
| 両方とも前のリビジョン前のリビジョン次のリビジョン | 前のリビジョン | ||
| cgfs:shaded_triangles [2024/06/14 00:52] – freemikan | cgfs:shaded_triangles [2025/12/12 15:57] (現在) – Replace overused back_inserters freemikan | ||
|---|---|---|---|
| 行 1: | 行 1: | ||
| - | < | + | ====== DrawPixelだけで三角形を描く (3) 明暗をつける ====== |
| + | |||
| + | {{: | ||
| + | |||
| + | [[https:// | ||
| + | |||
| + | <file cpp> | ||
| #include < | #include < | ||
| 行 27: | 行 33: | ||
| } | } | ||
| - | | + | |
| - | | + | |
| for (int i = i0; i <= i1; ++i) { | for (int i = i0; i <= i1; ++i) { | ||
| - | *out++ = d; | + | *out = d; |
| + | ++out; | ||
| d += a; | d += a; | ||
| - | } | ||
| - | } | ||
| - | |||
| - | void DrawLine(vec2 const &p0, vec2 const &p1, Color const &color) { | ||
| - | auto x0 = p0.x; | ||
| - | auto y0 = p0.y; | ||
| - | auto x1 = p1.x; | ||
| - | auto y1 = p1.y; | ||
| - | |||
| - | if (std:: | ||
| - | if (x0 > x1) { | ||
| - | std:: | ||
| - | std:: | ||
| - | } | ||
| - | auto i0 = static_cast< | ||
| - | auto i1 = static_cast< | ||
| - | auto ys = std:: | ||
| - | Interpolate(i0, | ||
| - | for (int i = i0; i <= i1; ++i) { | ||
| - | PutPixel(i, ys[i - i0], color); | ||
| - | } | ||
| - | } else { | ||
| - | if (y0 > y1) { | ||
| - | std:: | ||
| - | std:: | ||
| - | } | ||
| - | auto i0 = static_cast< | ||
| - | auto i1 = static_cast< | ||
| - | auto xs = std:: | ||
| - | Interpolate(i0, | ||
| - | for (int i = i0; i <= i1; ++i) { | ||
| - | PutPixel(xs[i - i0], i, color); | ||
| - | } | ||
| - | } | ||
| - | } | ||
| - | |||
| - | void DrawWireframeTriangle(vec2 const &p0, | ||
| - | vec2 const &p1, | ||
| - | vec2 const &p2, | ||
| - | Color const &color) { | ||
| - | DrawLine(p0, | ||
| - | DrawLine(p1, | ||
| - | DrawLine(p2, | ||
| - | } | ||
| - | |||
| - | void DrawFilledTriangle(vec2 const &p0, | ||
| - | vec2 const &p1, | ||
| - | vec2 const &p2, | ||
| - | Color const &color) { | ||
| - | vec2 P0{p0}, P1{p1}, P2{p2}; | ||
| - | if (P1.y < P0.y) { | ||
| - | std:: | ||
| - | } | ||
| - | if (P2.y < P0.y) { | ||
| - | std:: | ||
| - | } | ||
| - | if (P2.y < P1.y) { | ||
| - | std:: | ||
| - | } | ||
| - | |||
| - | auto i0 = static_cast< | ||
| - | auto i1 = static_cast< | ||
| - | auto i2 = static_cast< | ||
| - | auto x01 = std:: | ||
| - | auto x12 = std:: | ||
| - | auto x02 = std:: | ||
| - | |||
| - | Interpolate(i0, | ||
| - | Interpolate(i1, | ||
| - | Interpolate(i0, | ||
| - | |||
| - | x01.pop_back(); | ||
| - | |||
| - | auto x012 = std:: | ||
| - | assert(x012.size() == x02.size()); | ||
| - | |||
| - | auto corner = std:: | ||
| - | std:: | ||
| - | |||
| - | auto x_left = x012; | ||
| - | auto x_right = x02; | ||
| - | auto m = x012.size() / 2; | ||
| - | if (x02[m] < x012[m]) { | ||
| - | x_left = x02; | ||
| - | x_right = x012; | ||
| - | } | ||
| - | |||
| - | for (int y = i0; y < i2; ++y) { | ||
| - | auto x_begin = static_cast< | ||
| - | auto x_end = static_cast< | ||
| - | for (int x = x_begin; x < x_end; ++x) { | ||
| - | PutPixel(x, y, color); | ||
| - | } | ||
| } | } | ||
| } | } | ||
| 行 151: | 行 65: | ||
| VertexPositionIntensity const &p2, | VertexPositionIntensity const &p2, | ||
| Color const &color) { | Color const &color) { | ||
| + | using std::swap; | ||
| + | |||
| VertexPositionIntensity P0{p0}, P1{p1}, P2{p2}; | VertexPositionIntensity P0{p0}, P1{p1}, P2{p2}; | ||
| if (P1.y < P0.y) { | if (P1.y < P0.y) { | ||
| - | | + | swap(P1, P0); |
| } | } | ||
| if (P2.y < P0.y) { | if (P2.y < P0.y) { | ||
| - | | + | swap(P2, P0); |
| } | } | ||
| if (P2.y < P1.y) { | if (P2.y < P1.y) { | ||
| - | | + | swap(P2, P1); |
| } | } | ||
| - | | + | |
| - | | + | |
| - | | + | |
| - | | + | std:: |
| - | | + | std:: |
| Interpolate(yi0, | Interpolate(yi0, | ||
| Interpolate(yi0, | Interpolate(yi0, | ||
| - | | + | std:: |
| - | | + | std:: |
| Interpolate(yi1, | Interpolate(yi1, | ||
| Interpolate(yi1, | Interpolate(yi1, | ||
| - | | + | std:: |
| - | | + | std:: |
| Interpolate(yi0, | Interpolate(yi0, | ||
| Interpolate(yi0, | Interpolate(yi0, | ||
| + | // remove an overlapping point at x01.back and x12.front | ||
| x01.pop_back(); | x01.pop_back(); | ||
| assert(x01.size() + x12.size() == x02.size()); | assert(x01.size() + x12.size() == x02.size()); | ||
| + | // remove an overlapping point at h01.back and h12.front | ||
| h01.pop_back(); | h01.pop_back(); | ||
| assert(h01.size() + h12.size() == h02.size()); | assert(h01.size() + h12.size() == h02.size()); | ||
| - | | + | std:: |
| - | | + | std::merge(x01.begin(), |
| - | std::copy(x12.begin(), x12.end(), corner_x012); | + | |
| - | | + | std:: |
| - | | + | std::merge(h01.begin(), |
| - | | + | |
| + | | ||
| + | assert(h012.size() == h02.size()); | ||
| + | assert(x012.size() == h012.size()); | ||
| auto m = x012.size() / 2; | auto m = x012.size() / 2; | ||
| 行 202: | 行 122: | ||
| if (x02[m] < x012[m]) { | if (x02[m] < x012[m]) { | ||
| - | | + | swap(x_left, |
| - | | + | swap(h_left, |
| } | } | ||
| - | | + | std:: |
| for (int y = yi0; y <= yi2; ++y) { | for (int y = yi0; y <= yi2; ++y) { | ||
| - | | + | |
| - | | + | |
| - | //~ h_segment.resize(x_r - x_l + 1); | ||
| h_segment.clear(); | h_segment.clear(); | ||
| Interpolate(x_l, | Interpolate(x_l, | ||
| 行 218: | 行 137: | ||
| for (int x = x_l; x <= x_r; ++x) { | for (int x = x_l; x <= x_r; ++x) { | ||
| - | | + | |
| - | PutPixel(x, y, shaded_color); | + | PutPixel(x, y, color_scaled(color, |
| } | } | ||
| } | } | ||
| 行 225: | 行 144: | ||
| int main() { | int main() { | ||
| - | InitWindow(Cw, | + | InitWindow(Cw, |
| VertexPositionIntensity p0{-100, 200, 1.0}; | VertexPositionIntensity p0{-100, 200, 1.0}; | ||
| 行 241: | 行 160: | ||
| } | } | ||
| } | } | ||
| - | </codeprism> | + | </file> |
