a few days ago I started programming with the Irrlicht Engine. I did some tutorials and read on the forums and in the API...
What I want to do is a terrain with loading a heightmap-file and texturing it later.
Since I cannot ensure map-sizes of (2^n+1) I couldn't use the ITerrainSceneNode.
With the addTerrainMesh()-function of the SceneManager I got a working result and was able to display the terrain.
Unfortunately with much less FPS than I had in other examples. I think its because addTerrainMesh() is
using IImage instead of ITexture, which is not loaded into hardware-buffers or sth the like(?).
Therefore I programmed a small class implementing the IMeshLoader interface to become my own heightmap-loader in the future,
using a custom file format. To test this I'm currently not reading something from the file,
its just creating the hardcoded mesh from Tutorial 3 inside the createMesh() function.
Code: Select all
#define NUM_VERTICES 4
#define VERTICES_PER_POLY 3
class MyMeshLoader : public irr::scene::IMeshLoader {
private:
irr::scene::SAnimatedMesh animatedMesh;
irr::scene::SMesh mesh;
irr::scene::SMeshBuffer meshBuffer;
irr::video::SMaterial material;
irr::core::aabbox3d<irr::f32> box;
irr::video::S3DVertex *vertices;
irr::u16 *indices;
public:
MyMeshLoader() {
std::cout << "MyMeshLoader() constructor call\n";
}
virtual ~MyMeshLoader() {
std::cout << "MyMeshLoader() destructor call\n";
if (vertices) free(vertices);
if (indices) free(indices);
}
virtual irr::scene::IAnimatedMesh *createMesh(irr::io::IReadFile *file) {
std::cout << "MyMeshLoader.createMesh() called\n";
bool failed = false;
vertices = (irr::video::S3DVertex *)malloc(NUM_VERTICES * sizeof(irr::video::S3DVertex));
if (!vertices) failed = true;
indices = (irr::u16 *)malloc(NUM_VERTICES * VERTICES_PER_POLY * sizeof(irr::u16));
if (!indices) failed = true;
if (failed) {
std::cout << "Failed to malloc resources for the mesh\n";
if (vertices) free(vertices);
if (indices) free(indices);
}
irr::u16 indicesInit[] = { 0,2,3, 2,1,3, 1,0,3, 2,0,1 };
int i = 0;
for (i = 0; i < NUM_VERTICES * VERTICES_PER_POLY; ++i) {
indices[i] = indicesInit[i];
}
vertices[0] = irr::video::S3DVertex(0,0,10, 1,1,0, irr::video::SColor(255,0,255,255), 0, 1);
vertices[1] = irr::video::S3DVertex(10,0,-10, 1,0,0, irr::video::SColor(255,255,0,255), 1, 1);
vertices[2] = irr::video::S3DVertex(0,20,0, 0,1,1, irr::video::SColor(255,255,255,0), 1, 0);
vertices[3] = irr::video::S3DVertex(-10,0,-10, 0,0,1, irr::video::SColor(255,0,255,0), 0, 0);
material.Lighting = false;
meshBuffer.Material = material;
box.reset(vertices[0].Pos);
for (i = 1; i < NUM_VERTICES; ++i) {
box.addInternalPoint(vertices[i].Pos);
}
meshBuffer.setBoundingBox(box);
meshBuffer.append(&vertices[0], NUM_VERTICES, &indices[0], NUM_VERTICES * VERTICES_PER_POLY);
mesh.setBoundingBox(box);
mesh.addMeshBuffer(&meshBuffer);
animatedMesh.setBoundingBox(box);
animatedMesh.addMesh(&mesh);
std::cout << "MyMeshLoader.createMesh() finished\n";
return &animatedMesh;
}
virtual bool isALoadableFileExtension(irr::io::path const &filename) const {
irr::core::string<irr::c8> extension = filename.subString(filename.findLast('.'), filename.size(), true);
std::cout << "File extension is: " << extension.c_str() << '\n';
return extension == ".sta";
}
};
With this mesh I then create the SceneNode.
--> Is it correct to call meshLoader->drop() after passing him to the SceneManager?
Code: Select all
MyMeshLoader *meshLoader = new MyMeshLoader();
smgr->addExternalMeshLoader(meshLoader);
meshLoader->drop();
irr::scene::IAnimatedMesh *animatedMesh = smgr->getMesh("../terrain/mymesh.sta");
if (!animatedMesh) {
std::cout << "Could not load 'mymesh.sta'\n";
return 1;
}
irr::scene::IAnimatedMeshSceneNode *node = smgr->addAnimatedMeshSceneNode(animatedMesh, NULL, -1,
irr::core::vector3df(0,0,0), irr::core::vector3df(0,0,0), irr::core::vector3df(1.0f,1.0f,1.0f));
pops up, which is not very helpful
The following is the console output from running the programm once (including program closure, at this moment the above error appears)
So I'm not sure why this happens, probably something failes during the cleanup.
A hint into the right direction would be nice.
Is it the initialization of my mesh in the meshloader which is insufficient?
Do I have to pass specific other information along with my meshloader to the SceneManager?
Best regards and thanks in advance