Hi embers,
I’m running into a problem rendering strokes in the Cinder PoScene block. My source graphics are SVGs, which I convert to Shape2ds. Each contour should then be rendered with a different fill colour and black stroke and support transparency. However, at present PoScene lists strokes as a //TO DO item in poShape.cpp.
Under the hood, PoScene converts Shape2d to a VBO mesh. By converting each Shape2d contour to a VboMesh and running two passes over each mesh(one for wireframe and one for fill), I’m able to get shapes with fill and stroke as long as each shape remains opaque. As soon as I introduce transparency, the wireframe shows through the fill. Here are 3 images to illustrate the problem and the code I’ve added to poShape.cpp so far.
'void Shape::render()
{
ci::TriMesh::Format format = ci::TriMesh::Format();
format.mTexCoords0Dims = 2;
format.mPositionsDims = 2;
format.mNormalsDims = 3;
int numContours = mCiShape2d.getNumContours();
//Create a TriMesh and VboMesh for each of our shape2d contours
//Then create a vector of VBO meshes to hold all of the contours
for (int i = 0; i < numContours; ++i)
{
ci::Path2d thisPath = mCiShape2d.getContour(i);
ci::TriMeshRef triMesh = ci::TriMesh::create(ci::Triangulator(thisPath, (float)mPrecision).calcMesh(ci::Triangulator::WINDING_POSITIVE), format);
mVboMesh = ci::gl::VboMesh::create(*triMesh);
mVboMeshes.push_back(mVboMesh);
}
}
void Shape::draw()
{
ci::gl::enableAlphaBlending();
ci::gl::color(ci::ColorA(getFillColor(), getAppliedAlpha()));
std::vectorci::Color thisColors = getFillColors();
float artAlpha = 1.0f;
float wireframeStrokeWidth = 4.0;
for (int i = 0; i < mVboMeshes.size(); ++i)
{
//DRAW VboMesh WIREFRAME
ci::gl::setWireframeEnabled(true);
//gl::lineWidth - DEPRECATED, BUT STILL SUPPORTED IN NVIDIA DRIVER
ci::gl::lineWidth(wireframeStrokeWidth);
ci::gl::color(ci::ColorA(0, 0, 0, artAlpha));
ci::gl::ScopedGlslProg shaderScp(ci::gl::getStockShader(ci::gl::ShaderDef().color()));
ci::gl::draw(mVboMeshes[i]);
ci::gl::setWireframeEnabled(false);
//DRAW VboMesh FILL
ci::Color thisColor = thisColors[i];
ci::gl::color(ci::ColorA(thisColor, artAlpha));
ci::gl::ScopedGlslProg shaderScp2(ci::gl::getStockShader(ci::gl::ShaderDef().color()));
ci::gl::draw(mVboMeshes[i]);
}
}`
To get around the problem, I want to render only the outline of the wireframe. To do so, it seems that I need to calculate the adjacent TriMesh vertices then construct a VboMesh to create the outline.
I found this post on the the Cinder Discourse forum Adjacency to index buffer from trimesh, where @mettrelapaix managed to solve the problem for an obj file.
I read through the post and the logic and code snippets made sense but I’m not sure how to put it all together, especially integrating the adjacency calculation code and it’s dependencies from the glsl 4.0 cookbook into my Cinder project.
@paul.houx has suggested
“Perhaps we should add this adjacency stuff to Cinder, might come in handy. A gl::VboMeshAdj that takes a TriMesh, gl::VboMesh or even a geom::Source as input, for instance.”
I’d like to support this request. In trying to solve this problem, I’ve come across many people trying to outline VboMeshes and it appears to be a commonly needed functionality.
Meanwhile, can someone please help me put the pieces together to achieve this?
Many thanks,
Ken
Cinder 0.9.0 release
VS 2013 Community Edition
Win 7 64 bit