- const s32 argb_wstep = 4 * width;
- const s32 alpha_threshold = 1;
-
- scene::IMeshBuffer* buf = new scene::SMeshBuffer();
- video::SColor c(255,255,255,255);
-
- // Front and back
- {
- video::S3DVertex vertices[8] =
- {
- video::S3DVertex(-0.5,-0.5,-0.5, 0,0,-1, c, 0,1),
- video::S3DVertex(-0.5,+0.5,-0.5, 0,0,-1, c, 0,0),
- video::S3DVertex(+0.5,+0.5,-0.5, 0,0,-1, c, 1,0),
- video::S3DVertex(+0.5,-0.5,-0.5, 0,0,-1, c, 1,1),
- video::S3DVertex(+0.5,-0.5,+0.5, 0,0,+1, c, 1,1),
- video::S3DVertex(+0.5,+0.5,+0.5, 0,0,+1, c, 1,0),
- video::S3DVertex(-0.5,+0.5,+0.5, 0,0,+1, c, 0,0),
- video::S3DVertex(-0.5,-0.5,+0.5, 0,0,+1, c, 0,1),
- };
- u16 indices[12] = {0,1,2,2,3,0,4,5,6,6,7,4};
- buf->append(vertices, 8, indices, 12);
- }
-
- // "Interior"
- // (add faces where a solid pixel is next to a transparent one)
- u8* solidity = new u8[(width+2) * (height+2)];
- u32 wstep = width + 2;
- for (u32 y = 0; y < height + 2; ++y)
- {
- u8* scanline = solidity + y * wstep;
- if (y == 0 || y == height + 1)
- {
- for (u32 x = 0; x < width + 2; ++x)
- scanline[x] = 0;
- }
- else
- {
- scanline[0] = 0;
- u8* argb_scanline = data + (y - 1) * argb_wstep;
- for (u32 x = 0; x < width; ++x)
- scanline[x+1] = (argb_scanline[x*4+3] >= alpha_threshold);
- scanline[width + 1] = 0;
- }
- }
-
- // without this, there would be occasional "holes" in the mesh
- f32 eps = 0.01;
-
- for (u32 y = 0; y <= height; ++y)
- {
- u8* scanline = solidity + y * wstep + 1;
- for (u32 x = 0; x <= width; ++x)
- {
- if (scanline[x] && !scanline[x + wstep])
- {
- u32 xx = x + 1;
- while (scanline[xx] && !scanline[xx + wstep])
- ++xx;
- f32 vx1 = (x - eps) / (f32) width - 0.5;
- f32 vx2 = (xx + eps) / (f32) width - 0.5;
- f32 vy = 0.5 - (y - eps) / (f32) height;
- f32 tx1 = x / (f32) width;
- f32 tx2 = xx / (f32) width;
- f32 ty = (y - 0.5) / (f32) height;
- video::S3DVertex vertices[8] =
- {
- video::S3DVertex(vx1,vy,-0.5, 0,-1,0, c, tx1,ty),
- video::S3DVertex(vx2,vy,-0.5, 0,-1,0, c, tx2,ty),
- video::S3DVertex(vx2,vy,+0.5, 0,-1,0, c, tx2,ty),
- video::S3DVertex(vx1,vy,+0.5, 0,-1,0, c, tx1,ty),
- };
- u16 indices[6] = {0,1,2,2,3,0};
- buf->append(vertices, 4, indices, 6);
- x = xx - 1;
- }
- if (!scanline[x] && scanline[x + wstep])
- {
- u32 xx = x + 1;
- while (!scanline[xx] && scanline[xx + wstep])
- ++xx;
- f32 vx1 = (x - eps) / (f32) width - 0.5;
- f32 vx2 = (xx + eps) / (f32) width - 0.5;
- f32 vy = 0.5 - (y + eps) / (f32) height;
- f32 tx1 = x / (f32) width;
- f32 tx2 = xx / (f32) width;
- f32 ty = (y + 0.5) / (f32) height;
- video::S3DVertex vertices[8] =
- {
- video::S3DVertex(vx1,vy,-0.5, 0,1,0, c, tx1,ty),
- video::S3DVertex(vx1,vy,+0.5, 0,1,0, c, tx1,ty),
- video::S3DVertex(vx2,vy,+0.5, 0,1,0, c, tx2,ty),
- video::S3DVertex(vx2,vy,-0.5, 0,1,0, c, tx2,ty),
- };
- u16 indices[6] = {0,1,2,2,3,0};
- buf->append(vertices, 4, indices, 6);
- x = xx - 1;
- }