Main Page Namespace List Class Hierarchy Compound List File List Namespace Members Compound Members File Members Related Pages
Introduction
This an example of how to write a new processor. Here we want to define a processor displaying in a GL context the normals of the model and controlling the length of the normals.
GL::NormalRendererGlobalVariables
To control the length of the normals displayed to screen, we have to memorize a variable global to the traverse of the scene graph. That's why we derive GlobalVariables and add methods to set and get the length.
GL::NormalRendererGroupingVisitor
To draw the normals in the correct coordinates, we have to push the Transform matrices. Thus we define enterTransform and leaveTransform operating on the GL::Transform
node that belongs to the Grouping component.
GL::NormalRendererGeometry3DVisitor
To draw the normals we have to visit the GL::IndexedFaceSet
node which already has the vertexArrays updated to be rendered by OpenGL. We just have to get the normals from the arrays. That is here that we get the length of the normals. The instance of the GL::NormalRendererGlobalVariables
is given by GVManager which controls the number of instances.
GL::NormalRenderer
This is the facade of the processor which aggregates the visitors of the different components. It also contains the algorithm GL::DefaultDFS
of traversal of the scene graph.
NormalX3DGLScene
We customize SimpleX3DGLScene
by adding methods relative to the display of the normals.
code
GLNormalRendererGlobalVariables
GLNormalRendererGlobalVariables.h
#ifndef GLNORMALRENDERERGLOBALVARIABLES_H
#define GLNORMALRENDERERGLOBALVARIABLES_H
#include <X3DTK/kernel.h>
namespace X3DTK {
namespace GL {
class NormalRendererGlobalVariables : public GlobalVariables
{
public:
NormalRendererGlobalVariables();
virtual ~NormalRendererGlobalVariables();
void setNormalLength(float value);
float getNormalLength() const {return _normalLength;};
private:
float _normalLength;
};
}
}
#endif
GLNormalRendererGlobalVariables.cpp
#include "GLNormalRendererGlobalVariables.h"
namespace X3DTK {
namespace GL {
NormalRendererGlobalVariables::NormalRendererGlobalVariables()
: GlobalVariables(), _normalLength(1.0f)
{
}
NormalRendererGlobalVariables::~NormalRendererGlobalVariables()
{
}
void NormalRendererGlobalVariables::setNormalLength(float value)
{
_normalLength = value;
}
}
}
GLNormalRendererGroupingVisitor
GLNormalRendererGroupingVisitor.h
#ifndef GLNORMALRENDERERGROUPINGVISITOR_H
#define GLNORMALRENDERERGROUPINGVISITOR_H
#include <X3DTK/kernel.h>
namespace X3DTK {
namespace GL {
class NormalRendererGroupingVisitor : public GroupingVisitor
{
public:
NormalRendererGroupingVisitor();
virtual ~NormalRendererGroupingVisitor();
virtual void enterTransform(Transform *T) const;
virtual void leaveTransform(Transform *T) const;
};
}
}
#endif
GLNormalRendererGroupingVisitor.cpp
#include "GLNormalRendererGroupingVisitor.h"
namespace X3DTK {
namespace GL {
NormalRendererGroupingVisitor::NormalRendererGroupingVisitor()
: GroupingVisitor()
{
defineNewEnterFunction<NormalRendererGroupingVisitor, Transform>(&NormalRendererGroupingVisitor::enterTransform);
defineNewLeaveFunction<NormalRendererGroupingVisitor, Transform>(&NormalRendererGroupingVisitor::leaveTransform);
}
NormalRendererGroupingVisitor::~NormalRendererGroupingVisitor()
{
}
void NormalRendererGroupingVisitor::enterTransform(Transform *T) const
{
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glMultMatrixf(&T->getTransformMatrix().front());
}
void NormalRendererGroupingVisitor::leaveTransform(Transform *T) const
{
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
}
}
}
GLNormalRendererGeometry3DVisitor
GLNormalRendererGeometry3DVisitor.h
#ifndef GLNORMALRENDERERGEOMETRY3DVISITOR_H
#define GLNORMALRENDERERGEOMETRY3DVISITOR_H
#include "GLNormalRendererGlobalVariables.h"
#include <X3DTK/kernel.h>
namespace X3DTK {
namespace GL {
class NormalRendererGeometry3DVisitor : public Geometry3DVisitor
{
public:
NormalRendererGeometry3DVisitor();
virtual ~NormalRendererGeometry3DVisitor();
virtual void enterIndexedFaceSet(IndexedFaceSet *I) const;
protected:
NormalRendererGlobalVariables *globalVariables;
};
}
}
#endif
GLNormalRendererGeometry3DVisitor.cpp
#include "GLNormalRendererGeometry3DVisitor.h"
#include <vector>
using namespace std;
namespace X3DTK {
namespace GL {
NormalRendererGeometry3DVisitor::NormalRendererGeometry3DVisitor()
: Geometry3DVisitor()
{
defineNewEnterFunction<NormalRendererGeometry3DVisitor, IndexedFaceSet>(&NormalRendererGeometry3DVisitor::enterIndexedFaceSet);
globalVariables = GVManager::getInstanceOf<NormalRendererGlobalVariables>();
}
NormalRendererGeometry3DVisitor::~NormalRendererGeometry3DVisitor()
{
}
void NormalRendererGeometry3DVisitor::enterIndexedFaceSet(IndexedFaceSet *G) const
{
float coef = globalVariables->getNormalLength();
glColor3f(1.0f, 0.0f, 0.0f);
glDisable(GL_LIGHTING);
if ((G->getColor()) && (G->getTexCoord()))
{
const vector<T2F_C4F_N3F_V3F> &vertexArray = G->T2F_C4F_N3F_V3F_vertexArray();
glBegin(GL_LINES);
for (vector<T2F_C4F_N3F_V3F>::const_iterator it = vertexArray.begin(); it != vertexArray.end(); ++it)
{
SFVec3f vertex = (*it).vertex;
SFVec3f vnormal = vertex + coef*(*it).normal;
glVertex3fv(vertex.f_data());
glVertex3fv(vnormal.f_data());
}
glEnd();
}
if ((G->getColor()) && (!G->getTexCoord()))
{
const vector<C4F_N3F_V3F> &vertexArray = G->C4F_N3F_V3F_vertexArray();
glBegin(GL_LINES);
for (vector<C4F_N3F_V3F>::const_iterator it = vertexArray.begin(); it != vertexArray.end(); ++it)
{
SFVec3f vertex = (*it).vertex;
SFVec3f vnormal = vertex + coef*(*it).normal;
glVertex3fv(vertex.f_data());
glVertex3fv(vnormal.f_data());
}
glEnd();
}
if ((!G->getColor()) && (G->getTexCoord()))
{
const vector<T2F_N3F_V3F> &vertexArray = G->T2F_N3F_V3F_vertexArray();
glBegin(GL_LINES);
for (vector<T2F_N3F_V3F>::const_iterator it = vertexArray.begin(); it != vertexArray.end(); ++it)
{
SFVec3f vertex = (*it).vertex;
SFVec3f vnormal = vertex + coef*(*it).normal;
glVertex3fv(vertex.f_data());
glVertex3fv(vnormal.f_data());
}
glEnd();
}
if ((!G->getColor()) && (!G->getTexCoord()))
{
const vector<N3F_V3F> &vertexArray = G->N3F_V3F_vertexArray();
glBegin(GL_LINES);
for (vector<N3F_V3F>::const_iterator it = vertexArray.begin(); it != vertexArray.end(); ++it)
{
SFVec3f vertex = (*it).vertex;
SFVec3f vnormal = vertex + coef*(*it).normal;
glVertex3fv(vertex.f_data());
glVertex3fv(vnormal.f_data());
}
glEnd();
}
glEnable(GL_LIGHTING);
}
}
}
GLNormalRenderer
GLNormalRenderer.h
#ifndef GLNORMALRENDERER_H
#define GLNORMALRENDERER_H
#include "GLNormalRendererGlobalVariables.h"
#include <X3DTK/kernel.h>
namespace X3DTK {
namespace GL {
class NormalRenderer
{
public:
NormalRenderer();
virtual ~NormalRenderer();
void setNormalLength(float value);
void setComponentVisitor(X3DComponentVisitor *component);
virtual void render(SFNode N) const;
protected:
DFS *dfs;
NormalRendererGlobalVariables *globalVariables;
};
}
}
#endif
GLNormalRenderer.cpp
#include "GLNormalRenderer.h"
#include "GLNormalRendererGeometry3DVisitor.h"
#include "GLNormalRendererGroupingVisitor.h"
#include <iostream>
using namespace std;
namespace X3DTK {
namespace GL {
NormalRenderer::NormalRenderer()
{
dfs = new DefaultDFS();
globalVariables = GVManager::getInstanceOf<NormalRendererGlobalVariables>();
dfs->setComponentVisitor(new NormalRendererGeometry3DVisitor());
dfs->setComponentVisitor(new NormalRendererGroupingVisitor());
}
NormalRenderer::~NormalRenderer()
{
delete dfs;
}
void NormalRenderer::setNormalLength(float value)
{
globalVariables->setNormalLength(value);
}
void NormalRenderer::setComponentVisitor(X3DComponentVisitor *component)
{
dfs->setComponentVisitor(component);
}
void NormalRenderer::render(SFNode N) const
{
glDisable(GL_COLOR_MATERIAL);
dfs->traverse(N);
}
}
}
NormalX3DGLScene
NormalX3DGLScene.h
#ifndef NORMALX3DGLSCENE_H
#define NORMALX3DGLSCENE_H
#include <X3DTK/simplex3dglscene.h>
#include "GLNormalRenderer.h"
namespace X3DTK {
class NormalX3DGLScene : public SimpleX3DGLScene
{
public:
NormalX3DGLScene();
virtual ~NormalX3DGLScene();
void setNormal(bool value);
void setNormalLength(float value);
virtual void draw();
private:
GL::NormalRenderer *_normalRenderer;
bool _normal;
};
}
#endif
NormalX3DGLScene.cpp
#include "NormalX3DGLScene.h"
namespace X3DTK {
NormalX3DGLScene::NormalX3DGLScene()
: SimpleX3DGLScene(), _normalRenderer(new GL::NormalRenderer()), _normal(false)
{
}
NormalX3DGLScene::~NormalX3DGLScene()
{
delete _normalRenderer;
}
void NormalX3DGLScene::setNormal(bool value)
{
_normal = value;
}
void NormalX3DGLScene::setNormalLength(float value)
{
_normalRenderer->setNormalLength(value);
}
void NormalX3DGLScene::draw()
{
SimpleX3DGLScene::draw();
if (_normal)
_normalRenderer->render(glscene);
}
}
Viewer
Viewer.h
Viewer.cpp
Generated on Mon Sep 8 16:35:28 2003 for X3DToolKit by
1.3