Commit 2c0d552c authored by Sebastian Eichelbaum's avatar Sebastian Eichelbaum

[CHANGE] - improved shader for trimesh renderer and some performance optimizations.

parent ae9e2db3
......@@ -237,12 +237,11 @@ osg::ref_ptr< osg::Node > wge::generateSolidBoundingBoxNode( const WBoundingBox&
return transform;
}
osg::ref_ptr< osg::Geometry > wge::convertToOsgGeometry( WTriangleMesh::SPtr mesh, bool includeNormals, bool lighting )
{
return wge::convertToOsgGeometry( mesh.get(), includeNormals, lighting );
}
osg::ref_ptr< osg::Geometry > wge::convertToOsgGeometry( WTriangleMesh* mesh, bool includeNormals, bool lighting )
osg::ref_ptr< osg::Geometry > wge::convertToOsgGeometry( WTriangleMesh::SPtr mesh,
const WColor& defaultColor,
bool includeNormals,
bool lighting,
bool useMeshColor)
{
osg::ref_ptr< osg::Geometry> geometry( new osg::Geometry );
geometry->setVertexArray( mesh->getVertexArray() );
......@@ -261,7 +260,7 @@ osg::ref_ptr< osg::Geometry > wge::convertToOsgGeometry( WTriangleMesh* mesh, bo
geometry->addPrimitiveSet( surfaceElement );
// add the mesh colors
if ( mesh->getVertexColorArray() )
if ( mesh->getVertexColorArray() && useMeshColor )
{
geometry->setColorArray( mesh->getVertexColorArray() );
geometry->setColorBinding( osg::Geometry::BIND_PER_VERTEX );
......@@ -269,7 +268,7 @@ osg::ref_ptr< osg::Geometry > wge::convertToOsgGeometry( WTriangleMesh* mesh, bo
else
{
osg::ref_ptr< osg::Vec4Array > colors = osg::ref_ptr< osg::Vec4Array >( new osg::Vec4Array );
colors->push_back( osg::Vec4( 1.0, 1.0, 1.0, 1.0 ) );
colors->push_back( defaultColor );
geometry->setColorArray( colors );
geometry->setColorBinding( osg::Geometry::BIND_OVERALL );
}
......@@ -301,12 +300,16 @@ osg::ref_ptr< osg::Geometry > wge::convertToOsgGeometry( WTriangleMesh* mesh, bo
}
}
// enable VBO
geometry->setUseDisplayList( false );
geometry->setUseVertexBufferObjects( true );
return geometry;
}
osg::ref_ptr< osg::Geometry > wge::convertToOsgGeometry( WTriangleMesh::SPtr mesh, const WColoredVertices& colorMap, const WColor& defaultColor, bool includeNormals, bool lighting )
{
osg::Geometry* geometry = convertToOsgGeometry( mesh.get(), includeNormals, lighting );
osg::Geometry* geometry = convertToOsgGeometry( mesh, defaultColor, includeNormals, lighting, false );
// ------------------------------------------------
// colors
......
......@@ -96,24 +96,17 @@ namespace wge
* \param mesh the WTriangleMesh used as input
* \param includeNormals When true, calculate the vertex normals and include
* them into the geometry.
* \param defaultColor This color is used in case the useMeshColor parameter is false or no colors are defined in the mesh.
* \param lighting if true, a standard lighting is activated for this geometry
* \param useMeshColor if true, the mesh color is used. If false, the defaultColor is used.
* \return an osg::Geometry containing the mesh
* \note mesh cannot be const since osg::Geometry needs non-const pointers to the contained arrays
*/
osg::ref_ptr< osg::Geometry > convertToOsgGeometry( WTriangleMesh::SPtr mesh, bool includeNormals = false, bool lighting = false );
/**
* Extract the vertices and triangles from a WTriangleMesh and save them
* into an osg::Geometry. It can use the normals and per-vertex colors of the mesh.
*
* \param mesh the WTriangleMesh used as input
* \param includeNormals When true, calculate the vertex normals and include
* them into the geometry.
* \param lighting if true, a standard lighting is activated for this geometry
* \return an osg::Geometry containing the mesh
* \note mesh cannot be const since osg::Geometry needs non-const pointers to the contained arrays
*/
osg::ref_ptr< osg::Geometry > WGE_EXPORT convertToOsgGeometry( WTriangleMesh* mesh, bool includeNormals = false, bool lighting = false );
osg::ref_ptr< osg::Geometry > convertToOsgGeometry( WTriangleMesh::SPtr mesh,
const WColor& defaultColor = WColor( 1.0, 1.0, 1.0, 1.0 ),
bool includeNormals = false,
bool lighting = false,
bool useMeshColor = true );
/**
* Extract the vertices and triangles from a WTriangleMesh and save them
......@@ -132,7 +125,8 @@ namespace wge
osg::ref_ptr< osg::Geometry > WGE_EXPORT convertToOsgGeometry( WTriangleMesh::SPtr mesh, const WColoredVertices& colorMap,
const WColor& defaultColor = WColor( 1.0, 1.0, 1.0, 1.0 ),
bool includeNormals = false,
bool lighting = false );
bool lighting = false
);
/**
* Generates a line geode with thickness and color as parameters.
......
......@@ -95,7 +95,7 @@ osg::ref_ptr< osg::Vec3Array > wge::generateCuboidQuadNormals( const std::vector
return vertices;
}
WTriangleMesh wge::triangulate( const std::vector< WPosition >& points, double transformationFactor )
WTriangleMesh::SPtr wge::triangulate( const std::vector< WPosition >& points, double transformationFactor )
{
WAssert( points.size() > 2, "The Delaunay triangulation needs at least 3 vertices!" );
......@@ -150,7 +150,5 @@ WTriangleMesh wge::triangulate( const std::vector< WPosition >& points, double t
}
// I needed this reconversion using osgVec3Array because the triangulator changed my positions somehow.
WTriangleMesh mesh( wge::osgVec3Array( points ), triangles );
return mesh;
return WTriangleMesh::SPtr( new WTriangleMesh( wge::osgVec3Array( points ), triangles ) );
}
......@@ -124,7 +124,7 @@ namespace wge
* triangulation
* \return triangulation as WTriangleMesh
*/
WTriangleMesh WGE_EXPORT triangulate( const std::vector< WPosition >& points, double transformationFactor = 0.0 );
WTriangleMesh::SPtr WGE_EXPORT triangulate( const std::vector< WPosition >& points, double transformationFactor = 0.0 );
}
#endif // WGEGEOMETRYUTILS_H
......@@ -45,6 +45,16 @@ class WGEFunctorCallback: public WGECallbackTraits< Type >::CallbackType
{
public:
/**
* Shared pointer.
*/
typedef osg::ref_ptr< WGEFunctorCallback > SPtr;
/**
* Const shared pointer.
*/
typedef osg::ref_ptr< const WGEFunctorCallback > ConstSPtr;
/**
* The type of functor supported in this callback.
*/
......
......@@ -650,8 +650,7 @@ osg::ref_ptr< osg::Node > WMEEGView::drawHeadSurface()
const std::size_t nbPositions = positions.size();
WTriangleMesh mesh = wge::triangulate( positions, -0.005 );
osg::ref_ptr< osg::Geometry > geometry = wge::convertToOsgGeometry( &mesh, true );
osg::ref_ptr< osg::Geometry > geometry = wge::convertToOsgGeometry( wge::triangulate( positions, -0.005 ), WColor( 1.0, 1.0, 1.0, 1.0 ), true );
osg::Vec4Array* colors = new osg::Vec4Array;
colors->push_back( osg::Vec4( 1.0f, 1.0f, 1.0f, 1.0f ) );
......
......@@ -99,13 +99,18 @@ void WMTriangleMeshRenderer::properties()
m_opacity->setMin( 0.0 );
m_opacity->setMax( 100.0 );
m_externalColormapGroup = m_properties->addPropertyGroup( "External ColorMap.", "All the properties for the external colormap." );
m_externalDefaultColor = m_externalColormapGroup->addProperty( "Default Color", "The color where no mapping is defined.",
WColor( .9f, .9f, 0.9f, 1.0f ), m_propCondition );
m_useExternalColormap = m_externalColormapGroup->addProperty( "External Colormap", "If enabled, the renderer uses the external colormap "
"specified on the input connector \"colorMap\". If not, it uses the mesh colors.", false, m_propCondition );
// Allow the user to select different colormodes
boost::shared_ptr< WItemSelection > colorModes( boost::shared_ptr< WItemSelection >( new WItemSelection() ) );
colorModes->addItem( "Single Color", "The whole surface is colored using the default color." );
colorModes->addItem( "From Mesh", "The surface is colored according to the mesh." );
colorModes->addItem( "From colormap connector", "The surface is colored using the colormap on colorMap connector." );
m_colorMode = m_properties->addProperty( "Color-Mode", "Choose one of the available colorings.", colorModes->getSelectorFirst(),
m_propCondition );
WPropertyHelper::PC_SELECTONLYONE::addTo( m_colorMode );
// this is the color used if single color is selected
m_color = m_properties->addProperty( "Default Color", "The color of of the surface.",
WColor( .9f, .9f, 0.9f, 1.0f ), m_propCondition );
// call WModule's initialization
WModule::properties();
......@@ -146,12 +151,18 @@ void WMTriangleMeshRenderer::moduleMain()
////////////////////////////////////////////////////////////////////////////////////////////////////
// create a OSG node, which will contain the triangle data and allows easy transformations:
WGEManagedGroupNode::SPtr moduleNode( new WGEManagedGroupNode( m_active ) );
osg::StateSet* moduleNodeState = moduleNode->getOrCreateStateSet();
WKernel::getRunningKernel()->getGraphicsEngine()->getScene()->insert( moduleNode );
WGEManagedGroupNode::SPtr m_moduleNode( new WGEManagedGroupNode( m_active ) );
osg::StateSet* moduleNodeState = m_moduleNode->getOrCreateStateSet();
WKernel::getRunningKernel()->getGraphicsEngine()->getScene()->insert( m_moduleNode );
// set the member function "updateTransformation" as callback
WGEFunctorCallback< osg::Node >::SPtr transformationCallback(
new WGEFunctorCallback< osg::Node >( boost::bind( &WMTriangleMeshRenderer::updateTransformation, this ) )
);
// load the GLSL shader:
m_shader = osg::ref_ptr< WGEShader > ( new WGEShader( "WMTriangleMeshRenderer", m_localPath ) );
osg::ref_ptr< WGEShader > shader( new WGEShader( "WMTriangleMeshRenderer", m_localPath ) );
shader->apply( m_moduleNode );
// set the opacity and material color property as GLSL uniforms:
moduleNodeState->addUniform( new WGEPropertyUniform< WPropDouble >( "u_opacity", m_opacity ) );
......@@ -196,33 +207,48 @@ void WMTriangleMeshRenderer::moduleMain()
}
++*progress;
// Should the colorMap be enabled?
if( m_useExternalColormap->get() && colorMap )
// now create the mesh but handle the color mode properly
WItemSelector s = m_colorMode->get( true );
if( s.getItemIndexOfSelected( 0 ) == 0 )
{
// this simply converts our triangle mesh to an OSG geometry.
geometry = wge::convertToOsgGeometry( mesh, *colorMap, m_externalDefaultColor->get(), true, true );
// use single color
geometry = wge::convertToOsgGeometry( mesh, m_color->get(), true, true, false );
}
else if( m_useExternalColormap->get() )
else if( s.getItemIndexOfSelected( 0 ) == 1 )
{
warnLog() << "External colormap not connected.";
geometry = wge::convertToOsgGeometry( mesh, true, true );
// take color from mesh
geometry = wge::convertToOsgGeometry( mesh, m_color->get(), true, true, true );
}
else
{
geometry = wge::convertToOsgGeometry( mesh, true, true );
// take color from map
if( colorMap )
{
geometry = wge::convertToOsgGeometry( mesh, *colorMap, m_color->get(), true, true );
}
else
{
warnLog() << "External colormap not connected. Using default color.";
geometry = wge::convertToOsgGeometry( mesh, m_color->get(), true, true, false );
}
}
++*progress;
// done. Set the new drawable
geode->addDrawable( geometry );
moduleNode->clear();
moduleNode->insert( geode );
m_moduleNode->clear();
m_moduleNode->insert( geode );
debugLog() << "Rendering Mesh done";
++*progress;
progress->finish();
}
// it is important to always remove the modules again
WKernel::getRunningKernel()->getGraphicsEngine()->getScene()->remove( moduleNode );
WKernel::getRunningKernel()->getGraphicsEngine()->getScene()->remove( m_moduleNode );
}
void WMTriangleMeshRenderer::updateTransformation()
{
// this function is called every frame. It allows safely updating m_moduleNode states and properties.
}
......@@ -34,6 +34,7 @@
class WTriangleMesh;
class WGEShader;
class WGEManagedGroupNode;
/**
* This module renders the triangle mesh given at its input connector
......@@ -125,24 +126,24 @@ private:
WPropBool m_mainComponentOnly;
/**
* The group containing all the external colormap props
* The color of the mesh to be rendered.
*/
WPropGroup m_externalColormapGroup;
WPropColor m_color;
/**
* Coloring per vertex. This uses the specified colormap in m_colorMapInput.
* Which colormode should be used?
*/
WPropBool m_useExternalColormap;
WPropSelection m_colorMode;
/**
* The color of the mesh to be rendered if in external colormap-mode.
* Updates the transformation matrix of the main node. Called every frame.
*/
WPropColor m_externalDefaultColor;
void updateTransformation();
/**
* The shader doing proper lighting and colormapping.
* The node containing all geometry nodes.
*/
osg::ref_ptr< WGEShader > m_shader;
WGEManagedGroupNode::SPtr m_moduleNode;
};
#endif // WMTRIANGLEMESHRENDERER_H
......@@ -22,26 +22,29 @@
//
//---------------------------------------------------------------------------
varying vec4 VaryingTexCoord0;
#version 120
uniform int opacity;
/**
* The normal.
*/
varying vec3 v_normal;
#include "WGELighting-fragment.glsl"
/**
* The opacity specified by the user in [0,100]
*/
uniform float u_opacity;
#include "WGEShadingTools.glsl"
void main()
{
vec4 col = gl_Color;
vec4 ambient = vec4( 0.0 );
vec4 diffuse = vec4( 0.0 );
vec4 specular = vec4( 0.0 );
calculateLighting( -normal, gl_FrontMaterial.shininess, ambient, diffuse, specular );
col = ( ambient * col / 2.0 ) + ( diffuse * col ) + ( specular * col / 3.0 );
col = clamp( col, 0.0, 1.0 );
col.a = float( opacity ) * 0.01; // MacOS X has old shader spec, no implicit conversion to float takes place
// calculate lighting
float light = blinnPhongIlluminationIntensity( normalize( -v_normal ) );
col*=light;
// finally, apply opacity
col.a = u_opacity * 0.01;
gl_FragColor = col;
}
......@@ -22,17 +22,19 @@
//
//---------------------------------------------------------------------------
varying vec4 VaryingTexCoord0;
#version 120
#include "WGELighting-vertex.glsl"
/**
* The normal.
*/
varying vec3 v_normal;
void main()
{
VaryingTexCoord0 = gl_MultiTexCoord0;
prepareLight();
// get normal
v_normal = gl_NormalMatrix * gl_Normal;
// apply standard pipeline
gl_FrontColor = gl_Color;
gl_Position = ftransform();
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment