This example shows how to add custom information to a voxel and pass them the vertices.
#include "blub/log/global.hpp"
#include "blub/log/system.hpp"
#include "blub/math/colour.hpp"
#include "blub/math/math.hpp"
#include "blub/math/quaternion.hpp"
#include "blub/math/sphere.hpp"
#include "blub/math/transform.hpp"
#include "blub/serialization/callBaseObject.hpp"
#include "blub/sync/identifier.hpp"
#include "blub/procedural/voxel/config.hpp"
#include "blub/procedural/voxel/edit/axisAlignedBox.hpp"
#include "blub/procedural/voxel/edit/sphere.hpp"
#include "blub/procedural/voxel/simple/accessor.hpp"
#include "blub/procedural/voxel/simple/container/inMemory.hpp"
#include "blub/procedural/voxel/simple/renderer.hpp"
#include "blub/procedural/voxel/simple/surface.hpp"
#include "blub/procedural/voxel/terrain/accessor.hpp"
#include "blub/procedural/voxel/terrain/surface.hpp"
#include "blub/procedural/voxel/terrain/renderer.hpp"
#include "blub/procedural/voxel/tile/container.hpp"
#include "blub/procedural/voxel/tile/renderer.hpp"
#include "blub/procedural/voxel/tile/surface.hpp"
#include "OgreTile.hpp"
#include "Handler.hpp"
#include <boost/function.hpp>
template <typename configType>
{
public:
static pointer create(Ogre::SceneManager *sc,
Ogre::String materialName,
{
const pointer result(
new customOgreTile(sc, materialName, *graphicDispatcher));
result->initialise();
return result;
}
void addCustomVertexDeclaration(Ogre::VertexDeclaration* decl)
{
decl->addElement(2, 0, Ogre::VET_COLOUR_ABGR, Ogre::VES_DIFFUSE);
}
void addCustomVertexInformation(Ogre::VertexBufferBinding* binding, const typename t_base::t_vertices& vertices)
{
t_base::addCustomVertexInformation(binding, vertices);
{
Ogre::HardwareVertexBufferSharedPtr diffuseBuffer;
const size_t sizeVertex = Ogre::VertexElement::getTypeSize(Ogre::VET_COLOUR_ABGR);
diffuseBuffer = Ogre::HardwareBufferManager::getSingleton().createVertexBuffer(
sizeVertex, vertices.size(), Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY);
uint8* toWriteTo(static_cast<uint8*>(diffuseBuffer->lock(Ogre::HardwareBuffer::HBL_DISCARD)));
for (uint32 ind = 0; ind < vertices.size(); ++ind)
{
const uint32 indColour = ind*4;
const typename t_base::t_vertex&
vertex(vertices.at(ind));
toWriteTo[indColour+0] = uint8(
vertex.
diffuse.
r*255.);
toWriteTo[indColour+1] = uint8(
vertex.diffuse.
g*255.);
toWriteTo[indColour+2] = uint8(
vertex.diffuse.
b*255.);
toWriteTo[indColour+3] = uint8(
vertex.diffuse.
a*255.);
}
diffuseBuffer->unlock();
binding->setBinding(2, diffuseBuffer);
}
}
protected:
Ogre::String materialName,
: t_base(sc, materialName, graphicDispatcher)
{;}
};
template <typename configType>
{
public:
static pointer create()
{
}
static pointer createCopy(pointer toCopy)
{
}
typename t_base::t_vertex createVertex(
const vector3int32& voxelPos,
const typename t_base::t_voxel &voxel0,
const typename t_base::t_voxel &voxel1,
const vector3 &position,
const vector3 &normal)
{
typename t_base::t_vertex result(t_base::createVertex(voxelPos, voxel0, voxel1, position, normal));
if (voxel0.diffuse ==
colour(1.,1.,1.,1.))
{result.diffuse = voxel1.diffuse;}
else
{result.diffuse = voxel0.diffuse;}
return result;
}
typename t_base::t_vertex createVertexLod(
const vector3int32& voxelPos,
const typename t_base::t_voxel &voxel0,
const typename t_base::t_voxel &voxel1,
const vector3 &position,
const vector3 &normal)
{
typename t_base::t_vertex result(t_base::createVertexLod(voxelPos, voxel0, voxel1, position, normal));
result.diffuse = (voxel0.diffuse + voxel1.diffuse) / 2;
return result;
}
protected:
};
template <typename configType>
{
public:
typedef configType t_config;
static pointer create(const ::blub::sphere& desc)
{
}
bool calculateOneVoxel(
const vector3& pos,
typename t_base::t_voxel* resultVoxel)
const override
{
const bool result(t_base::calculateOneVoxel(pos, resultVoxel));
if (!result)
{
return false;
}
resultVoxel->diffuse = diffuseToSet;
return true;
}
protected:
: t_base(desc)
{
const uint32 colourToRand = math::rand()%3;
switch (colourToRand)
{
case 0:
diffuseToSet.r = math::randReal(); break;
case 1:
diffuseToSet.g = math::randReal(); break;
case 2:
diffuseToSet.b = math::randReal(); break;
default:
BASSERT(true);
}
}
};
{
, diffuse(1., 1., 1.)
{;}
};
{
};
{
typedef container<config> t_container;
typedef accessor<config> t_accessor;
template <typename configType>
{
};
typedef surface<config> t_surface;
template <typename configType>
{
};
typedef renderer<config> t_renderer;
};
typedef typename t_config::t_renderer::t_tile t_renderTile;
void createSphere(t_voxelContainer *container,
const vector3 &position,
const bool &cut);
int main(int , char* [])
{
blub::log::system::addConsole();
blub::log::system::addFile("voxelterrain.log");
{
return EXIT_FAILURE;
}
handler.
camera->setPosition(
vector3(20., 0., -50.));
{
return EXIT_FAILURE;
}
scopedPointer<t_voxelContainer> voxelContainer;
scopedPointer<t_voxelAccessor> voxelAccessor;
scopedPointer<t_voxelSurface> voxelSurface;
scopedPointer<t_voxelRenderer> voxelRenderer;
t_cameraIdentifier cameraIdentifier;
{
const int32 numLod(3);
voxelContainer.reset(new t_voxelContainer(terrainDispatcher));
voxelAccessor.reset(new t_voxelAccessor(terrainDispatcher, *voxelContainer, numLod));
voxelSurface.reset(new t_voxelSurface(terrainDispatcher, *voxelAccessor));
Ogre::MaterialPtr material = Ogre::MaterialManager::getSingleton().create("customVertexInformation", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
Ogre::Pass *pass = material->getTechnique(0)->getPass(0);
pass->setVertexColourTracking(Ogre::TVC_AMBIENT);
pass->setLightingEnabled(true);
const t_voxelRenderer::t_createTileCallback callbackCreate = boost::bind(t_renderTile::create, handler.
renderScene,
"customVertexInformation", &handler.
graphicDispatcher);
lodRadien[0] = t_config::voxelsPerTile*2.0;
lodRadien[1] = t_config::voxelsPerTile*2.0;
lodRadien[2] = t_config::voxelsPerTile*2.0;
voxelRenderer.reset(new t_voxelRenderer(terrainDispatcher, *voxelSurface, lodRadien));
voxelRenderer->setCreateTileCallback(callbackCreate);
cameraIdentifier = sync::identifier::create();
voxelRenderer->addCamera(cameraIdentifier, handler.camera->getPosition());
handler.
signalFrame()->connect(
[&] (real)
{
voxelRenderer->updateCamera(cameraIdentifier, handler.camera->getPosition());
}
);
handler.
signalMouseGotPressed()->connect(
[&] (bool &left)
{
createSphere(voxelContainer.get(), handler.camera->getPosition()+handler.camera->getDirection()*10., !left);
}
);
}
{
sphereEditCut->setCut(true);
voxelContainer->editVoxel(sphereEdit);
}
{
terrainDispatcher.start();
handler.
renderSystem->startRendering();
terrainDispatcher.stop();
}
return EXIT_SUCCESS;
}
void createSphere(t_voxelContainer *container,
const vector3 &position,
const bool &cut)
{
sphereEdit->setCut(cut);
}