# 21.4. 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 SoPointSet SoPointSet shape.

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. Figure 21.7. Point field bars computed within a geometry shader Figure 21.8. Simplified scene graph of GeometryShader.cxx

Example 21.2. Writing a geometry shader:

```main(int argc, char **argv)
{
...`
// Initialize the vertex and geometry shader

// Initialize and set the shader program
// Define the input geometry type which is POINTS because defined by an
// SoPointSet
// Define the output geometry type generated by the geometry shader which is
// a triangle strip set

// Uniform parameter to define the bar width

// Input geometry shader primitive (SoPointSet)

// Build the scene graph
...
}
```
```
```
```
```

```/* !!GLSL Vertex Shader */

void main()
{
// Transform the vertex (ModelViewProj matrix)
gl_Position = gl_Vertex;
gl_FrontColor = gl_FrontMaterial.diffuse;
}
```

```#version 120

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.position ) ), 0. ) *
gl_FrontColorIn );
}
/******************************************************************************/

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();
}
}
/******************************************************************************/
``` Figure 21.9. Shader usage for image base lighting and HDRI reflection (Data set courtesy DaimlerChrysler AG)