Open Inventor Release 2024.2.0
 
Loading...
Searching...
No Matches
Writing a Geometry shader

The following example computes within a geometry shader the geometry of point field bars from a set of 3D points which specify the X,Y coordinate of the center of each bar and the Z coordinate of the top of each bar. The 3D point set is defined by an SoPointSet shape.

The example source code is located in $OIVHOME/src/Inventor/examples/Features/Shaders/GeometryShader.

This example is written using GLSL (Open Inventor supports only GLSL geometry shaders).

When defining a geometry shader, it is mandatory to define also a vertex
shader.

Point field bars computed within a geometry shader

: Example : Writing a geometry shader:

Contents of GeometryShader.cxx

C++ :

main( int argc, char** argv )
{
...
// Initialize the vertex and geometry shader
SoVertexShader* vertexShader = new SoVertexShader;
SoGeometryShader* geometryShader = new SoGeometryShader;
vertexShader->sourceProgram.setValue( "../../../data/Shaders/histoShaderVtx.glsl" );
geometryShader->sourceProgram.setValue( "../../../data/Shaders/histoShaderGeom.glsl" );
// Initialize and set the shader program
SoShaderProgram* shaderProgram = new SoShaderProgram;
shaderProgram->shaderObject.set1Value( 0, vertexShader );
shaderProgram->shaderObject.set1Value( 1, geometryShader );
// Define the input geometry type which is POINTS because defined by an
// SoPointSet
shaderProgram->geometryInputType = SoShaderProgram::POINTS_INPUT;
// Define the output geometry type generated by the geometry shader which is
// a triangle strip set
shaderProgram->geometryOutputType = SoShaderProgram::TRIANGLE_STRIP_OUTPUT;
// Uniform parameter to define the bar width
HistoGeomShaderWidth = new SoShaderParameter1f;
HistoGeomShaderWidth->name = "BarWidth";
geometryShader->parameter.setValue( HistoGeomShaderWidth );
// Input geometry shader primitive (SoPointSet)
HistoGeomShaderShape = new SoPointSet;
HistoGeomShaderCoord = new SoCoordinate3;
// Build the scene graph
SoSeparator* geomShaderSep = new SoSeparator;
geomShaderSep->boundingBoxIgnoring = true;
geomShaderSep->addChild( shaderProgram );
geomShaderSep->addChild( HistoGeomShaderCoord );
geomShaderSep->addChild( HistoGeomShaderShape );
...
}

C# :

Java :

Contents of histoShaderVtx.glsl Vertex Shader:

/* !!GLSL Vertex Shader */
void
main()
{
// Transform the vertex (ModelViewProj matrix)
gl_Position = gl_Vertex;
gl_FrontColor = gl_FrontMaterial.diffuse;
}

Contents of histoShaderGeom.glsl Geometry Shader:

#version 120
#extension GL_EXT_geometry_shader4 : enable
uniform float BarWidth;
/******************************************************************************/
// Compute the diffuse color according to the normal.
vec4
computeDiffuseColor( vec3 normal )
{
vec3 tNormal = normalize( gl_NormalMatrix * normal );
return ( max( dot( tNormal, vec3( gl_LightSource[0].position ) ), 0. ) * gl_FrontColorIn[0] );
}
/******************************************************************************/
void
main( void )
{
int i;
for ( i = 0; i < gl_VerticesIn; i++ )
{
vec4 posIn = gl_PositionIn[i];
vec4 position;
position.w = posIn.w;
// 1st face
position.x = posIn.x - BarWidth;
position.y = posIn.y - BarWidth;
position.z = 0.0;
gl_Position = gl_ModelViewProjectionMatrix * position;
gl_FrontColor = computeDiffuseColor( vec3( 0, -1, 0 ) );
EmitVertex();
position.z = posIn.z;
gl_Position = gl_ModelViewProjectionMatrix * position;
EmitVertex();
position.x = posIn.x + BarWidth;
position.z = 0.0;
gl_Position = gl_ModelViewProjectionMatrix * position;
EmitVertex();
position.z = posIn.z;
gl_Position = gl_ModelViewProjectionMatrix * position;
EmitVertex();
EndPrimitive();
// 2nd face
...
...
EndPrimitive();
// 3rd face
...
...
EndPrimitive();
// 4th face
...
...
EndPrimitive();
// 5th face
...
...
EndPrimitive();
// 6th face
...
...
EndPrimitive();
}
}
/******************************************************************************/

Shader usage for image base lighting and HDRI reflection (Data set courtesy DaimlerChrysler AG)