[solved] mesh building is painfully slow & mesh flickers.
Posted: Sun Dec 27, 2015 4:10 am
exerpt from main function
function called
I'm not entirely certain why the mesh flickers in and out, other irrlicht projects with very similar meshing code do not (namely my main project, I'm trying to improve my slow mesher - it's too slow to be useful, 8.1 seconds for a 32^3 array, I haven't timed this 64^2 array but it's many seconds).
It's not a clipping issue either, first of all the mesh is huge, second of all I haven't ever seen the entire octree node get clipped.
Also it's not (likely) a driver issue - the same driver and irrlicht version can draw Q3 maps and 3D models loaded from elsewhere fine, logically the issue is thus with my code - but I don't know what it is.
Code: Select all
level = loadMap("data/3.png", &tileset);
SMesh *mesh = new SMesh();
SMeshBuffer *buf = NULL;
buf = new SMeshBuffer;
std::cout << "building level" << std::endl;
//This doesn't affect the speed at all, my theory is that buf->append ignores the fact that space is reserved already.
//even though I'm specifically NOT setting the reserved space as used -
//append SHOULD put it in the unused reserved space
buf->Indices.reallocate(level.size()*level[0].size());
buf->Vertices.reallocate(level.size()*level[0].size());
buildMesh(level, buf);
mesh->addMeshBuffer(buf);
buf->drop();
ISceneNode *node = NULL;
std::cout << "creating an octree scene node to speed things up" << std::endl;
node = smgr->addOctreeSceneNode(mesh, 0, -1, 4096);
node->setScale(vector3df(10.0f,10.0f,10.0f));
node->setMaterialTexture(0, driver->getTexture("data/2.png"));
node->setMaterialFlag(video::EMF_BILINEAR_FILTER, false);
node->setMaterialFlag(video::EMF_WIREFRAME, false);
node->setMaterialFlag(EMF_LIGHTING, false);
while(iDevice->run())
{
driver->beginScene(true, true, SColor(255,140,255,140));
smgr->drawAll();
driver->endScene();
}
iDevice->drop();
Code: Select all
void buildMesh(std::vector< std::vector< int > > input, SMeshBuffer *buf)
{
//This code builds corridors based on tile data.
//Currently it seems to generate some faces inverted and other faces on the wrong side of the grid
//However I can't really get a good look since it'll flicker out of existence at weird angles!
//Also it builds faces inside walls, this affects speed and memory usage but not drawing speed since it's an octree.
//I actually don't know why though, most of these faces are generated in tiles where the content SHOULD be 1 (wall)
//as opposed to 0 (AIR), image in post is an example of 1/0 expected (white is air, black is wall)
int tile1;
SColor c(255,255,255,255);
for(int x = 0; x < input.size(); x++)
{
for(int y = 0; y < input[0].size(); y++)
{
tile1 = 0;
if (x > 0)
tile1 = input.at(x-1).at(y);
if (tile1 == 0)
{
video::S3DVertex vertices[4] =
{
//These windings should be correct, I'm not sure what Nx, Ny, Nz do so I copied them from known good code, and set them to 1 (this code uses increments of 1, the other code uses increments of 2 and has them set to 2
video::S3DVertex(x-0 , 1 , y+0, -1, 1,-1, c, 0,0),
video::S3DVertex(x-0 , 0 , y+0, -1,-1,-1, c, 0,1),
video::S3DVertex(x-0 , 1 , y+1, -1, 1, 1, c, 1,0),
video::S3DVertex(x-0 , 0 , y+1, -1,-1, 1, c, 1,1),
};
u16 indices[6] = {2, 0, 1,
1, 3, 2,};
buf->append(vertices, 4, indices, 6);
}
tile1 = 0;
if (x < (input.size() - 1))
tile1 = input.at(x+1).at(y);
if (tile1 == 0)
{
video::S3DVertex vertices[4] =
{
video::S3DVertex(x+1 , 1 , y+0, 1, 1,-1, c, 1,0),
video::S3DVertex(x+1 , 0 , y+0, 1,-1,-1, c, 1,1),
video::S3DVertex(x+1 , 1 , y+1, 1, 1, 1, c, 0,0),
video::S3DVertex(x+1 , 0 , y+1, 1,-1, 1, c, 0,1),
};
u16 indices[6] = {0, 2, 3,
3, 1, 0,};
buf->append(vertices, 4, indices, 6);
}
tile1 = 0;
if (y > 0)
tile1 = input.at(x).at(y-1);
if (tile1 == 0)
{
video::S3DVertex vertices[4] =
{
video::S3DVertex(x+0 , 1 , y-1 , -1, 1, 1, c, 1,0),
video::S3DVertex(x+1 , 1 , y-1 , 1, 1, 1, c, 0,0),
video::S3DVertex(x+1 , 0 , y-1 , 1,-1, 1, c, 0,1),
video::S3DVertex(x+0 , 0 , y-1 , -1,-1, 1, c, 1,1),
};
u16 indices[6] = {3, 2, 1,
1, 0, 3,};
buf->append(vertices, 4, indices, 6);
}
tile1 = 0;
if (y < input.at(0).size() - 1)
tile1 = input.at(x).at(y+1);
if (tile1 == 0)
{
video::S3DVertex vertices[4] =
{
video::S3DVertex(x+0 , 1 , y+0, -1, 1,-1, c, 0,0),
video::S3DVertex(x+1 , 1 , y+0, 1, 1,-1, c, 1,0),
video::S3DVertex(x+1 , 0 , y+0, 1,-1,-1, c, 1,1),
video::S3DVertex(x+0 , 0 , y+0, -1,-1,-1, c, 0,1),
};
u16 indices[6] = {0, 1, 2,
2, 3, 0,};
buf->append(vertices, 4, indices, 6);
}
}
}
}
It's not a clipping issue either, first of all the mesh is huge, second of all I haven't ever seen the entire octree node get clipped.
Also it's not (likely) a driver issue - the same driver and irrlicht version can draw Q3 maps and 3D models loaded from elsewhere fine, logically the issue is thus with my code - but I don't know what it is.