[SOLVED, see final posts]
Dear PolyVox forums (in particular David and ker),
First I'd like to thank you all for your contributions towards the PolyVox engine. Having tackled the basic examples of PolyVox and Ogre integration, I have come across a roadblock when utilizing ker's example on Triplanar Texturing Using glsl (found here:
http://www.volumesoffun.com/polyvox/documentation/dokuwiki/glsl_ogre_for_triplanar_texturing_and_multiple_textures).
While the example is thorough and easy to follow, my attempts to implement the section of code responsible for fixing triangles where multiple materials appear gives me the following access violation:
Unhandled exception at 0x00841ab7 in OgreTest.exe: 0xC0000005: Access violation reading location 0x1e27cef4.Below is the constructor for the material/alpha vector and the rendering function (based on ker's example), which uses a mesh extracted from a volume region using the smooth surface extractor. Initially, when I setup the MaterialAlpha constructor verbatim to ker's, I ran into several build errors when using the struct elsewhere.
ma.material = {1, 2, 3}
1) ma.material Error: expression must be a modifiable lvalue
2) { Error: expected an expression
Once I was able to get it sorted out with my work-around, I ran into the access violation. Below is the code I am using.
Code:
struct MaterialAlpha
{
float material[3];
float alpha[3];
};
void Render::updateRegionRender(string nodeName, PolyVox::SurfaceMesh<PolyVox::PositionMaterialNormal> mesh, int x, int y, int z)
{
std::vector<PolyVox::PositionMaterialNormal>& vertices = mesh.m_vecVertices;
std::vector<uint32_t>& indices = mesh.m_vecTriangleIndices;
Ogre::SceneNode* ogreNode = mSceneMgr->getRootSceneNode()->createChildSceneNode(nodeName, Ogre::Vector3(x, y, z));
// Create Manual Ogre Object
Ogre::ManualObject* ogreMesh;
ogreMesh = mSceneMgr->createManualObject(nodeName);
ogreMesh->setDynamic(true);
// MaterialAlpha
assert(indices.size() % 3 == 0);
// find all triangles that contain more than 1 texture and create new vertices for them.
std::vector<MaterialAlpha> vertex_extra_data(vertices.size());
for(uint32_t i = 0; i < indices.size(); i+=3) {
uint32_t& i0 = indices.at(i);
uint32_t& i1 = indices.at(i+1);
uint32_t& i2 = indices.at(i+2);
const PolyVox::PositionMaterialNormal& vertex0 = vertices.at(i0);
const PolyVox::PositionMaterialNormal& vertex1 = vertices.at(i1);
const PolyVox::PositionMaterialNormal& vertex2 = vertices.at(i2);
MaterialAlpha ma;
ma.material[0] = vertex0.getMaterial();
ma.material[1] = vertex1.getMaterial();
ma.material[2] = vertex2.getMaterial();
if(vertex0.getMaterial() != vertex1.getMaterial()) {
if(vertex0.getMaterial() != vertex2.getMaterial()) {
ma.alpha[0] = 1.0;
ma.alpha[1] = 0.0;
ma.alpha[2] = 0.0;
vertex_extra_data.push_back(ma);
i0 = vertices.size();
vertices.push_back(vertex0);
ma.alpha[0] = 0.0;
ma.alpha[1] = 1.0;
ma.alpha[2] = 0.0;
vertex_extra_data.push_back(ma);
i1 = vertices.size();
vertices.push_back(vertex1);
ma.alpha[0] = 0.0;
ma.alpha[1] = 0.0;
ma.alpha[2] = 1.0;
vertex_extra_data.push_back(ma);
i2 = vertices.size();
vertices.push_back(vertex2);
} else {
// vertex 0 and 2 have the same material
ma.alpha[0] = 0.5;
ma.alpha[1] = 0.0;
ma.alpha[2] = 0.5;
vertex_extra_data.push_back(ma);
i0 = vertices.size();
vertices.push_back(vertex0);
ma.alpha[0] = 0.0;
ma.alpha[1] = 1.0;
ma.alpha[2] = 0.0;
vertex_extra_data.push_back(ma);
i1 = vertices.size();
vertices.push_back(vertex1);
ma.alpha[0] = 0.5;
ma.alpha[1] = 0.0;
ma.alpha[2] = 0.5;
vertex_extra_data.push_back(ma);
i2 = vertices.size();
vertices.push_back(vertex2);
}
} else {
if(vertex0.getMaterial() != vertex2.getMaterial()) {
// vertex 0 and 1 have same material
ma.alpha[0] = 0.5;
ma.alpha[1] = 0.5;
ma.alpha[2] = 0.0;
vertex_extra_data.push_back(ma);
i0 = vertices.size();
vertices.push_back(vertex0);
ma.alpha[0] = 0.5;
ma.alpha[1] = 0.5;
ma.alpha[2] = 0.0;
vertex_extra_data.push_back(ma);
i1 = vertices.size();
vertices.push_back(vertex1);
ma.alpha[0] = 0.0;
ma.alpha[1] = 0.0;
ma.alpha[2] = 1.0;
vertex_extra_data.push_back(ma);
i2 = vertices.size();
vertices.push_back(vertex2);
} else {
// all are equal
ma.alpha[0] = 1.0/3.0;
ma.alpha[1] = 1.0/3.0;
ma.alpha[2] = 1.0/3.0;
vertex_extra_data[i0] = ma;
vertex_extra_data[i1] = ma;
vertex_extra_data[i2] = ma;
}
}
}
// Begin writing to Manual Object
ogreMesh->begin("ApeTexture", Ogre::RenderOperation::OT_TRIANGLE_LIST);
// prepare the buffers
ogreMesh->estimateVertexCount(vertices.size());
ogreMesh->estimateIndexCount(indices.size());
for(uint32_t i = 0; i < vertices.size(); i++) {
const PolyVox::PositionMaterialNormal& vertex = vertices.at(i);
const MaterialAlpha& ma = vertex_extra_data.at(i);
PolyVox::Vector3DFloat vertex_pos = vertex.getPosition() + static_cast<PolyVox::Vector3DFloat>(mesh.m_Region.getLowerCorner()); // add chunk pos
ogreMesh->position(vertex_pos.getX(), vertex_pos.getY(), vertex_pos.getZ());
ogreMesh->normal(vertex.getNormal().getX(), vertex.getNormal().getY(), vertex.getNormal().getZ());
float x = vertex_pos.getX();
float y = vertex_pos.getY();
float z = vertex_pos.getZ();
const float faktor = 50;
for(int j = 0; j < 3; j++) {
ogreMesh->textureCoord(x/faktor, y/faktor, z/faktor, ma.alpha[j]);
}
ogreMesh->textureCoord(ma.material[0], ma.material[1], ma.material[2]);
}
for(uint32_t i = 0; i < indices.size(); i++) {
const uint32_t& index = indices.at(i);
ogreMesh->index(index);
}
// end writing
ogreMesh->end();
ogreNode->attachObject(ogreMesh);
}
The error appears at the pushback call located in the last correction section (where vertex0.getMaterial = vertex1.getMaterial != vertex2.getMaterial):
vertex_extra_data.push_back(ma);
This error occurs both in release and debug mode and is triggered part way through the run. At this point, the vertex_extra_data vector has a size of 25722 and a capacity of 38580. As the debugger shows, the assertion error comes from the vector.h standard header when pushing back a "non-element".
Code:
{ // push back a non-element
if (this->_Mylast == this->_Myend)
_Reserve(1);
_Orphan_range(this->_Mylast, this->_Mylast);
_Cons_val(this->_Alval,
this->_Mylast,
_Val);
++this->_Mylast;
}
}
Thank you for any and all assistance you may render. If there is any more information needed for clarification, just let me know.