Silhouette Edge Highlighting
Posted: Sun Apr 10, 2011 12:24 am
Hi all. I'm checking the feasibility of using edge highlighting in my game. I've used a lot of wiki example code and ideas from previous forum posts to create the following function.
A few lines of this are specific to my implementation (ones that use unitInTurn), but that should be obvious.
Obviously 90% of this is code I ripped off from somewhere else. I'm just trying to get an idea of whether this a) is possible and b) will give me the result I want.
The code works, but with a few issues:
1) Each sub-entity gets its own edges highlighted. I knew this would happen, but it certainly ruins the effect and I'm not sure how to "fix" it so that the whole entity's silhouette is highlighted instead of the individual parts.
2) Line thickness is an issue. I think my mesh may be partly occluding the lines, so sometimes I don't even get the full 1-pixel-wide line.
I also haven't tested the efficiency of this function (I'd have to pull out the buildEdgeList() part since that should only have to be done once).
In digging around the forums I realized that what I want is what Assaf Raman posted here (first post on the second page, ogre head with white border):
http://www.ogre3d.org/forums/viewtopic. ... 1&start=25
Unfortunately he didn't post source to that particular example. Whatever he did eliminates my problem #2, although I'm guessing he's using OpenGL's line width parameter, and I'm not sure I want to be tied to a particular renderer yet.
I also have to say I'm surprised there's not a wiki entry on this already (there is a talk page about a similar goal of highlighting the borders of a 2D map. This was part of the code I stole). I'd be glad to make one myself if I can get this thing working.
Any help? Suggestions? Similar issues?
A few lines of this are specific to my implementation (ones that use unitInTurn), but that should be obvious.
Code: Select all
{
size_t vertex_count,index_count;
int edgeNum = 0;
Ogre::Vector3* vertices;
unsigned long * indices;
// This function is directly from an Ogre Wiki entry and is just used to get the vertex list.
getMeshInformation(unitInTurn->entity->getMesh(),vertex_count,vertices,index_count,indices);
Ogre::Vector3 *vertexArray = new Ogre::Vector3[vertex_count];
vertexArray = vertices;
// Setup for edge detection
unitInTurn->entity->getMesh()->buildEdgeList();
Ogre::EdgeData * ed = unitInTurn->entity->getMesh()->getEdgeList();
Ogre::Vector4 cameraLight;
cameraLight.x = app->mCamera->getPosition().x;
cameraLight.y = app->mCamera->getPosition().y;
cameraLight.z = app->mCamera->getPosition().z;
cameraLight.w = 1.0;
ed->updateTriangleLightFacing(Ogre::Vector4(cameraLight));
// Setup for line creation
Ogre::SceneNode* myManualObjectNode = unitInTurn->node->createChildSceneNode("edge_node");
Ogre::MaterialPtr myManualObjectMaterial = Ogre::MaterialManager::getSingleton().create("manual1Material","General");
myManualObjectMaterial->setReceiveShadows(false);
myManualObjectMaterial->getTechnique(0)->setLightingEnabled(true);
myManualObjectMaterial->getTechnique(0)->getPass(0)->setDiffuse(0,0,1,0);
myManualObjectMaterial->getTechnique(0)->getPass(0)->setAmbient(0,0,1);
myManualObjectMaterial->getTechnique(0)->getPass(0)->setSelfIllumination(0,0,1);
// For all edges in this entity...
for (int i = 0; i < (int)ed->edgeGroups.size(); i++)
{
Ogre::EdgeData::EdgeGroup * group = &ed->edgeGroups[i];
for (int j = 0; j < (int)group->edges.size(); j++)
{
if (!group->edges[j].degenerate && (ed->triangleLightFacings[group->edges[j].triIndex[0]] != ed->triangleLightFacings[group->edges[j].triIndex[1]]))
{
// Edge should be highlighted.
Ogre::ManualObject* myManualObject = app->mSceneMgr->createManualObject();
myManualObject->begin("manual1Material", Ogre::RenderOperation::OT_LINE_LIST);
Ogre::Vector3 lineVertex1 = vertexArray[group->edges[j].vertIndex[0]];
Ogre::Vector3 lineVertex2 = vertexArray[group->edges[j].vertIndex[1]];
myManualObject->position(lineVertex1);
myManualObject->position(lineVertex2);
myManualObject->end();
myManualObjectNode->attachObject(myManualObject);
edgeNum++;
}
}
}
}
The code works, but with a few issues:
1) Each sub-entity gets its own edges highlighted. I knew this would happen, but it certainly ruins the effect and I'm not sure how to "fix" it so that the whole entity's silhouette is highlighted instead of the individual parts.
2) Line thickness is an issue. I think my mesh may be partly occluding the lines, so sometimes I don't even get the full 1-pixel-wide line.
I also haven't tested the efficiency of this function (I'd have to pull out the buildEdgeList() part since that should only have to be done once).
In digging around the forums I realized that what I want is what Assaf Raman posted here (first post on the second page, ogre head with white border):
http://www.ogre3d.org/forums/viewtopic. ... 1&start=25
Unfortunately he didn't post source to that particular example. Whatever he did eliminates my problem #2, although I'm guessing he's using OpenGL's line width parameter, and I'm not sure I want to be tied to a particular renderer yet.
I also have to say I'm surprised there's not a wiki entry on this already (there is a talk page about a similar goal of highlighting the borders of a 2D map. This was part of the code I stole). I'd be glad to make one myself if I can get this thing working.
Any help? Suggestions? Similar issues?