I now have, Triplanar Texture Minecraft Cubic Mesh in Irrlicht with
OUT GLSL.
And just look how messy it's getting. And this is after removing miles of out-commented code.
Code:
void calcMesh(SimpleVolume<uint8_t>& volData)
{
PolyVox::SurfaceMesh<PolyVox::PositionMaterialNormal> mesh;
//Transform voxel into mesh
PolyVox::CubicSurfaceExtractorWithNormals< PolyVox::SimpleVolume<uint8_t> > surfaceExtractor(&volData, volData.getEnclosingRegion(), &mesh);
surfaceExtractor.execute();
std::cout << mesh.getNoOfVertices() << ":Total Vertices.\n" << mesh.getNoOfIndices() << ":Total Indices.\n";// << meshPoly.noOfDegenerateTris() << "\n";
std::vector<uint32_t> indices = mesh.getIndices();
std::vector<PolyVox::PositionMaterialNormal> vertices = mesh.getVertices();
irr::scene::IDynamicMeshBuffer* buffer = new irr::scene::CDynamicMeshBuffer(irr::video::EVT_STANDARD, irr::video::EIT_16BIT);
irr::scene::IDynamicMeshBuffer* bufferX = new irr::scene::CDynamicMeshBuffer(irr::video::EVT_STANDARD, irr::video::EIT_16BIT);
irr::scene::IDynamicMeshBuffer* bufferY = new irr::scene::CDynamicMeshBuffer(irr::video::EVT_STANDARD, irr::video::EIT_16BIT);
irr::scene::IDynamicMeshBuffer* bufferZ = new irr::scene::CDynamicMeshBuffer(irr::video::EVT_STANDARD, irr::video::EIT_16BIT);
video::S3DVertex VertCoords;
video::S3DVertex VertCoordsX;
video::S3DVertex VertCoordsY;
video::S3DVertex VertCoordsZ;
video::SColor vertexColor = irr::video::SColor(255, 255, 255, 255);
irr::video::ITexture* temptexture = driver->getTexture("minecave.png");
//initialize
float U = 0.0f;
float V = 0.0f;
float cordoffsset = 0.5f;
buffer->getVertexBuffer().set_used(vertices.size());
bufferX->getVertexBuffer().set_used(vertices.size());
bufferY->getVertexBuffer().set_used(vertices.size());
bufferZ->getVertexBuffer().set_used(vertices.size());
for (size_t i = 0; i < vertices.size(); ++i) {
const PolyVox::Vector3DFloat& position = (vertices[i]).getPosition();
const PolyVox::Vector3DFloat& normal = (vertices[i]).getNormal();
const PolyVox::Vector3DFloat& material = (vertices[i]).getMaterial();
VertCoords = buffer->getVertexBuffer()[i];
VertCoords.Pos.set(position.getX(), position.getY(), position.getZ());
VertCoords.Normal.set(normal.getX(), normal.getY(), normal.getZ());
VertCoords.Color = vertexColor;
//For proper texture UV
if(fabsf(normal.getX())>fabsf(normal.getY()) && fabsf(normal.getX())>fabsf(normal.getZ())){
VertCoordsX.Pos.set(position.getX(), position.getY(), position.getZ());
VertCoordsX.Normal.set(normal.getX(), normal.getY(), normal.getZ());
U = position.getY()+cordoffsset;
V = position.getZ()+cordoffsset;
VertCoords.TCoords.set(U,V);//set the first buffer also
VertCoordsX.TCoords.set(U,V);
VertCoordsX = buffer->getVertexBuffer()[i];
}
else if(fabsf(normal.getY())>fabsf(normal.getX()) && fabsf(normal.getY())>fabsf(normal.getZ())){
VertCoordsY.Pos.set(position.getX(), position.getY(), position.getZ());
VertCoordsY.Normal.set(normal.getX(), normal.getY(), normal.getZ());
U = position.getX()+cordoffsset;
V = position.getZ()+cordoffsset;
VertCoords.TCoords.set(U,V);//set the first buffer also
VertCoordsY.TCoords.set(U,V);
VertCoordsY = buffer->getVertexBuffer()[i];
}
else {
VertCoordsZ.Pos.set(position.getX(), position.getY(), position.getZ());
VertCoordsZ.Normal.set(normal.getX(), normal.getY(), normal.getZ());
U = position.getX()+cordoffsset;
V = position.getY()+cordoffsset;
VertCoords.TCoords.set(U,V);//set the first buffer also
VertCoordsZ.TCoords.set(U,V);
VertCoordsZ = buffer->getVertexBuffer()[i];
}
//this part makes lots more sense now :P
buffer->getVertexBuffer()[i] = VertCoords;
bufferX->getVertexBuffer()[i] = VertCoordsX;
bufferY->getVertexBuffer()[i] = VertCoordsY;
bufferZ->getVertexBuffer()[i] = VertCoordsZ;
}
buffer->getIndexBuffer().set_used(indices.size());
bufferX->getIndexBuffer().set_used(indices.size());
bufferY->getIndexBuffer().set_used(indices.size());
bufferZ->getIndexBuffer().set_used(indices.size());
for (size_t i = 0; i < indices.size(); ++i) {
buffer->getIndexBuffer().setValue(i, indices[i]);
bufferX->getIndexBuffer().setValue(i, indices[i]);
bufferY->getIndexBuffer().setValue(i, indices[i]);
bufferZ->getIndexBuffer().setValue(i, indices[i]);
}
indices.clear();
vertices.clear();
// Recalculate bounding box
buffer->recalculateBoundingBox();
bufferX->recalculateBoundingBox();
bufferY->recalculateBoundingBox();
bufferZ->recalculateBoundingBox();
// Convert the mesh and hand it to Irrlicht
testMesh = new irr::scene::SMesh;
testMesh->addMeshBuffer(buffer);
testMesh->addMeshBuffer(bufferX);
testMesh->addMeshBuffer(bufferY);
testMesh->addMeshBuffer(bufferZ);
testMesh->recalculateBoundingBox();
levelMesh = device->getSceneManager()->addMeshSceneNode(testMesh,0,26);
// ENABLE DEBUG BBOX
levelMesh->setDebugDataVisible(irr::scene::EDS_MESH_WIRE_OVERLAY);
//levelMesh->setDebugDataVisible(irr::scene::EDS_BBOX_ALL);
//levelMesh->setDebugDataVisible(irr::scene::EDS_NORMALS);
//levelMesh->setDebugDataVisible(irr::scene::EDS_FULL);
levelMesh->getMaterial(0).setTexture(0, driver->getTexture("minecave.jpg"));
levelMesh->getMaterial(1).setTexture(0, driver->getTexture("wall.bmp"));
levelMesh->getMaterial(2).setTexture(0, driver->getTexture("sand.png"));
levelMesh->setMaterialFlag(video::EMF_LIGHTING, false);
buffer->drop();
bufferX->drop();
bufferY->drop();
bufferZ->drop();
testMesh->drop();
mesh.clear();
}
UPDATE
So after thinking this through all morning and last night, I've come up with a plan, but to understand the value of my plan, first, you must know my problem.

The Problem: When building custom mesh/models you're forced to realign the UV coords, and map all the UV for different textures. When building custom models in Irrlicht, you're forced to make a new mesh buffer every texture, and everytime you repeat the texture.. like say onto another axis.
3 axis (not including mirrored sides) times the number of materials (minecraft has hundreds) equals lots and lots of buffers.. namely 3x hundreds in this case. So to solve this problem took a bit of thought, because if I wanted to do some greedy meshing, then I needed to hold all of these material buffers in memory until the greedy mesher was done.. or at least it seemed that way.
The Solution: or at least MY solution, is to create a material buffer, a single buffer that will be reused until all materials have been properly applied to the model. This seems obvious in hindsight, however, most things do. Originally I had bad ideas, somehow thinking that the axial UV correction and the material assignment had to be in the same loop, however I've retained the 4 original buffers from the axial code because I realized that once those UV are set, any material could be applied AFTER and the UV will be mapped correctly. And that is another key element of this design is that the material assignment must be done AFTER the axial UV alignment.
Even this update seems a little silly to post now that it's worked out, but having a bit of a journal helps to stream this process along for me. And there is a technical challenge here, but this time not too hard of a solution to the problem. And having said all that I'll stop trying to explain the details of it and just leave you with "The Plan". Next post I'll show my progress with this.