This tutorial demonstrates how to improve the perception of the objects in a scene and how to perform hidden line removal wireframe rendering using the edge extraction and enhnacement capabilities of Visualization Library.
In this tutorial we will implement a simple application capable of loading models by drag&drop and applying edge enhancement and hidden line removal wireframe rendering to the whole scene. The user will also be able to interactively switch on and off various edge rendering features:
class App_EdgeRendering: public BaseDemo
{
public:
virtual String appletInfo()
{
return BaseDemo::appletInfo() +
"- '1' = edge rendering off.\n" +
"- '2' = edge rendering on: silhouette only.\n" +
"- '3' = edge rendering on: silhouette + creases.\n" +
"- '4' = edge rendering on: silhouette + creases + hidden lines.\n" +
"- '5' = edges only: silhouette + creases.\n" +
"- '6' = edges only: silhouette + creases + hidden lines.\n" +
"\n";
}
void initEvent()
{
mMainRendering = rendering()->as<Rendering>();
mSolidRenderer = mMainRendering->renderer();
mEdgeRenderer = new EdgeRenderer;
mEdgeRenderer->setFramebuffer(mSolidRenderer->framebuffer());
mMainRendering->renderers().push_back( mEdgeRenderer.get() );
mEdgeRenderer->setShowHiddenLines(true);
mEdgeRenderer->setShowCreases(true);
mEdgeRenderer->setCreaseAngle(35.0f);
mEdgeRenderer->setLineWidth(2.0f);
mEdgeRenderer->setSmoothLines(true);
mEdgeRenderer->setDefaultLineColor(black);
setupScene();
}
void setupScene()
{
ref<Light> camera_light = new Light;
ref<EnableSet> enables = new EnableSet;
ref<Effect> red_fx = new Effect;
red_fx->shader()->setEnableSet(enables.get());
red_fx->shader()->gocMaterial()->setDiffuse(red);
red_fx->shader()->setRenderState(camera_light.get(), 0);
ref<Effect> green_fx = new Effect;
green_fx->shader()->setEnableSet(enables.get());
green_fx->shader()->gocMaterial()->setDiffuse(green);
green_fx->shader()->setRenderState(camera_light.get(), 0);
ref<Effect> yellow_fx = new Effect;
yellow_fx->shader()->setEnableSet(enables.get());
yellow_fx->shader()->gocMaterial()->setDiffuse(yellow);
yellow_fx->shader()->setRenderState(camera_light.get(), 0);
ref<Geometry> geom3 =
makeCone (
vec3(+7,0,0),5,5, 20,
true);
geom1->computeNormals();
geom2->computeNormals();
geom3->computeNormals();
sceneManager()->tree()->addActor( geom1.get(), red_fx.get(), mMainRendering->transform() );
sceneManager()->tree()->addActor( geom2.get(), green_fx.get(), mMainRendering->transform() );
sceneManager()->tree()->addActor( geom3.get(), yellow_fx.get(), mMainRendering->transform() );
}
void keyPressEvent(
unsigned short ch,
EKey key)
{
BaseDemo::keyPressEvent(ch, key);
if (ch == '1')
{
mSolidRenderer->setEnableMask(0xFFFFFFFF);
mEdgeRenderer->setEnableMask(0);
Log::print("Edge rendering disabled.\n");
}
else
if (ch == '2')
{
mSolidRenderer->setEnableMask(0xFFFFFFFF);
mEdgeRenderer->setEnableMask(0xFFFFFFFF);
mEdgeRenderer->setShowCreases(false);
mEdgeRenderer->setShowHiddenLines(false);
Log::print("Edge rendering enabled. Creases = off, hidden lines = off.\n");
}
else
if (ch == '3')
{
mSolidRenderer->setEnableMask(0xFFFFFFFF);
mEdgeRenderer->setEnableMask(0xFFFFFFFF);
mEdgeRenderer->setShowCreases(true);
mEdgeRenderer->setShowHiddenLines(false);
Log::print("Edge rendering enabled. Creases = on, hidden lines = off.\n");
}
else
if (ch == '4')
{
mSolidRenderer->setEnableMask(0xFFFFFFFF);
mEdgeRenderer->setEnableMask(0xFFFFFFFF);
mEdgeRenderer->setShowCreases(true);
mEdgeRenderer->setShowHiddenLines(true);
Log::print("Edge rendering enabled. Creases = on, hidden lines = on.\n");
}
else
if (ch == '5')
{
mSolidRenderer->setEnableMask(0);
mEdgeRenderer->setEnableMask(0xFFFFFFFF);
mEdgeRenderer->setShowCreases(true);
mEdgeRenderer->setShowHiddenLines(false);
Log::print("Hidden line removal wireframe enabled. Creases = on, hidden lines = off.\n");
}
if (ch == '6')
{
mSolidRenderer->setEnableMask(0);
mEdgeRenderer->setEnableMask(0xFFFFFFFF);
mEdgeRenderer->setShowCreases(true);
mEdgeRenderer->setShowHiddenLines(true);
Log::print("Hidden line removal wireframe enabled. Creases = on, hidden lines = on.\n");
}
}
void resizeEvent(int w, int h)
{
Camera* camera = mMainRendering->camera();
camera->viewport()->setWidth ( w );
camera->viewport()->setHeight( h );
camera->setProjectionPerspective();
}
void loadModel(const std::vector<String>& files)
{
sceneManager()->tree()->actors()->clear();
mEdgeRenderer->clearCache();
for(size_t ifile=0; ifile<files.size(); ++ifile)
{
ref<ResourceDatabase> resource_db =
loadResource(files[ifile],
true);
if (!resource_db || resource_db->count<Actor>() == 0)
{
Log::error("No data found.\n");
continue;
}
std::vector< ref<Actor> > actors;
resource_db->get<Actor>(actors);
for(unsigned iactor=0; iactor<actors.size(); ++iactor)
{
ref<Actor> actor = actors[iactor].get();
actor->effect()->shader()->setRenderState( new Light, 0 );
actor->effect()->shader()->gocLightModel()->setTwoSide(true);
sceneManager()->tree()->addActor( actor.get() );
}
}
trackball()->adjustView( sceneManager(),
vec3(0,0,1),
vec3(0,1,0), 1.0f );
}
void fileDroppedEvent(const std::vector<String>& files) { loadModel(files); }
protected:
ref< Renderer > mSolidRenderer;
ref< EdgeRenderer > mEdgeRenderer;
ref<Rendering> mMainRendering;
};