%ffp /* title: Textured convex polygon drawing date: 2001-11-09 author: Martijn W. van der Lee / VanDerLee date id change ---------- ------ --------------------------------------------- 2001-12-28 MWVDL Added texture coordinates. Description ----------------------------------------------------------------- The U and V values are texture coordinates. They correspond to the X and Y coordinates of the texture image. Using this method allows for some very strange texturing posibilities like repeated textures or stretching. To map the texture to the polygon without stretching or rotation on a polygon with multiple vertices, scale the X and Y coordinates in range 0-99 to 0-255; vertex (30,50) would get texture coordinates (77,127). To do ----------------------------------------------------------------- - File I/O. - Use custom bitmap file as texture. - Add transformation tools for fun ((3D-)rotation, scale, etc.). - Verify y<=Y thingy. Is this correct??? - Interpolation (probably cosinal), requires more accurate UV buffers, currently can hold only 255 "steps". - "Shade" using an intensity buffer. */ ForEveryTile: { const int BFR_X = 0; const int BFR_Y = 100; const int BFR_U = 200; const int BFR_V = 300; const int BFR_A = 400; const int EMPTY = 0; const int PIXEL = 1; const int CH_CANVAS = 0; const int CH_ALPHA = 1; const int CH_U = 0; const int CH_V = 1; // Clear pixel canvas for(x = 0; x < X; ++x) for(y = 0; y < Y; ++y) tset(x, y, CH_CANVAS, EMPTY); // Define N-point convex polygon. // Remember; triangles are always convex by concept. // Negative values yield undefined results. // This stuff could be loaded from a file (hint!). // XXX, nnn YYY, nnn UUU, nnn VVV, nnn AAA, nnn put( 50, 1); put( 10, 101); put(255, 201); put( 0, 301); put( 0, 401); put( 10, 2); put( 50, 102); put( 0, 202); put( 0, 302); put( 0, 402); put( 30, 3); put( 90, 103); put( 0, 203); put(255, 303); put( 0, 403); put( 70, 4); put( 90, 104); put( 0, 204); put(255, 304); put( 0, 404); put( 90, 5); put( 50, 105); put(255, 205); put(255, 305); put( 0, 405); m = 5; // Number of points // Draw edges for(i1 = 1; i1 <= m; ++i1) { const int i2 = (i1 % m) + 1; const int X1 = get(BFR_X + i1) * X / 100; const int Y1 = get(BFR_Y + i1) * Y / 100; const int U1 = get(BFR_U + i1); const int V1 = get(BFR_V + i1); const int A1 = get(BFR_A + i1); const int X2 = get(BFR_X + i2) * X / 100; const int Y2 = get(BFR_Y + i2) * Y / 100; const int U2 = get(BFR_U + i2); const int V2 = get(BFR_V + i2); const int A2 = get(BFR_A + i2); // Draw a line from (X1, Y1) to (X2, Y2) for(y = min(Y1, Y2); y < max(Y1, Y2); ++y) { const int xx = ((y - Y1) * (X2 - X1) / (Y2 - Y1)) + X1; tset(xx, y, CH_CANVAS, PIXEL); tset(xx, y, CH_ALPHA, scl(y, Y1, Y2, A1, A2)); t2set(xx, y, CH_U, scl(y, Y1, Y2, U1, U2)); t2set(xx, y, CH_V, scl(y, Y1, Y2, V1, V2)); } } // Outerbound fill convex polygon for(y = 0; y < Y; ++y) { int b, e; for(b = 0; b < X && tget(b, y, CH_CANVAS) == EMPTY; ++b); for(e = X; e > 0 && tget(e, y, CH_CANVAS) == EMPTY; --e); // Scanline the line at Y-pos y if(b == e) { // Single pixel line? -> fix for scl(). const int xx1 = t2get(b, y, CH_U) * X / 255; const int yy1 = t2get(e, y, CH_V) * Y / 255; for(z = 0; z < Z; ++z) { pset(b, y, z, mix(src(b, y, z), src(xx1, yy1, z), CH_ALPHA, 255)); } } else { const int a1 = tget(b, y, CH_ALPHA); const int a2 = tget(e, y, CH_ALPHA); const int u1 = t2get(b, y, CH_U) * X / 255; const int u2 = t2get(e, y, CH_U) * X / 255; const int v1 = t2get(b, y, CH_V) * Y / 255; const int v2 = t2get(e, y, CH_V) * Y / 255; for(x = b; x <= e; ++x) { const int u = scl(x, b, e, u1, u2); const int v = scl(x, b, e, v1, v2); for(z = 0; z < Z; ++z) { pset(x, y, z, mix(src(x, y, z), src(u, v, z), scl(x, b, e, a1, a2), 255)); } } } } return true; }