1 // OpenSG GLSL shader example: Geometry Shader
3 // Demonstrates the use of the SHLChunk
4 // Implements a geometry shader which creates for each triangle an
5 // extra triangle showing the face normal.
7 #ifdef OSG_BUILD_ACTIVE
10 #include <OSGSimpleGeometry.h>
13 #include <OSGGLUTWindow.h>
14 #include <OSGSimpleSceneManager.h>
15 #include <OSGAction.h>
16 #include <OSGSceneFileHandler.h>
17 #include <OSGBaseFunctions.h>
21 #include <OSGTransform.h>
22 #include <OSGPointLight.h>
25 #include <OSGChunkMaterial.h>
26 #include <OSGMaterialChunk.h>
27 #include <OSGTextureChunk.h>
28 #include <OSGSHLChunk.h>
31 #include <OpenSG/OSGConfig.h>
32 #include <OpenSG/OSGSimpleGeometry.h>
33 #include <OpenSG/OSGGLUT.h>
34 #include <OpenSG/OSGGLEXT.h>
35 #include <OpenSG/OSGGLUTWindow.h>
36 #include <OpenSG/OSGSimpleSceneManager.h>
37 #include <OpenSG/OSGAction.h>
38 #include <OpenSG/OSGSceneFileHandler.h>
39 #include <OpenSG/OSGBaseFunctions.h>
41 #include <OpenSG/OSGNode.h>
42 #include <OpenSG/OSGGroup.h>
43 #include <OpenSG/OSGTransform.h>
44 #include <OpenSG/OSGPointLight.h>
46 #include <OpenSG/OSGImage.h>
47 #include <OpenSG/OSGChunkMaterial.h>
48 #include <OpenSG/OSGMaterialChunk.h>
49 #include <OpenSG/OSGTextureChunk.h>
50 #include <OpenSG/OSGSHLChunk.h>
55 // ------------------- global vars ----------------------
57 // The SimpleSceneManager to manage simple applications
58 SimpleSceneManagerRefPtr _mgr
;
62 // forward declaration so we can have the interesting stuff upfront
63 int setupGLUT( int *argc
, char *argv
[] );
65 static std::string _vertex_shader
=
68 " gl_Position = gl_Vertex;\n"
69 " gl_TexCoord[0] = vec4(abs(gl_Normal), 0.0);\n"
73 static std::string _fragment_shader
=
76 " gl_FragColor = gl_Color;\n"
80 // ok we create some triangles to draw the face normals.
81 static std::string _geometry_shader
=
83 "#extension GL_EXT_geometry_shader4 : enable\n"
87 " vec4 v1 = gl_PositionIn[0];\n"
88 " vec4 v2 = gl_PositionIn[1];\n"
89 " vec4 v3 = gl_PositionIn[2];\n"
91 " vec4 l1 = v2 - v1;\n"
92 " vec4 l2 = v3 - v1;\n"
94 " // create the original triangle.\n"
95 " gl_Position = gl_ModelViewProjectionMatrix * v1;\n"
96 " gl_FrontColor = vec4(0.0, 1.0, 0.0, 0.0);\n"
98 " gl_Position = gl_ModelViewProjectionMatrix * v2;\n"
99 " gl_FrontColor = vec4(0.0, 1.0, 0.0, 0.0);\n"
101 " gl_Position = gl_ModelViewProjectionMatrix * v3;\n"
102 " gl_FrontColor = vec4(0.0, 1.0, 0.0, 0.0);\n"
106 " vec3 l1n = l1.xyz;\n"
107 " vec3 l2n = l2.xyz;\n"
109 " vec3 N = cross(l1n.xyz, l2n.xyz);\n"
110 " N = normalize(N);\n"
111 " vec4 middle = v1 + 0.333 * l1 + 0.333 * l2;\n"
112 " // create the face normal triangle.\n"
113 " gl_Position = gl_ModelViewProjectionMatrix * middle;\n"
114 " gl_FrontColor = gl_TexCoordIn[0][0];\n"
116 " gl_FrontColor = gl_TexCoordIn[0][0];\n"
117 " gl_Position = gl_ModelViewProjectionMatrix * (middle + 0.1 * vec4(N, 0.0));\n"
119 " gl_FrontColor = gl_TexCoordIn[0][0];\n"
120 " gl_Position = gl_ModelViewProjectionMatrix * (middle + vec4(0.01,0.01,0.01,0.0));\n"
126 // Initialize GLUT & OpenSG and set up the scene
127 int main(int argc
, char **argv
)
133 int winid
= setupGLUT(&argc
, argv
);
135 // open a new scope, because the pointers below should go out of scope
136 // before entering glutMainLoop.
137 // Otherwise OpenSG will complain about objects being alive after shutdown.
139 // the connection between GLUT and OpenSG
140 GLUTWindowRefPtr gwin
= GLUTWindow::create();
141 gwin
->setGlutId(winid
);
142 gwin
->setSize( 800, 800 );
145 // Create the shader material
146 ChunkMaterialRefPtr cmat
= ChunkMaterial::create();
148 SHLChunkRefPtr shl
= SHLChunk::create();
149 shl
->setProgramParameter(GL_GEOMETRY_INPUT_TYPE_EXT
, GL_TRIANGLES_ADJACENCY_EXT
);
150 shl
->setProgramParameter(GL_GEOMETRY_OUTPUT_TYPE_EXT
, GL_TRIANGLES
);
151 // ok we create a maximum of 6 vertices.
152 shl
->setProgramParameter(GL_GEOMETRY_VERTICES_OUT_EXT
, 6);
154 shl
->setVertexProgram(_vertex_shader
);
155 shl
->setFragmentProgram(_fragment_shader
);
156 shl
->setGeometryProgram(_geometry_shader
);
161 _scene
= Node::create();
164 GeometryRefPtr geo
= makeTorusGeo(.8, 1.8, 32, 32);
165 geo
->setMaterial(cmat
);
167 NodeRefPtr torus
= Node::create();
170 // add torus to scene
171 GroupRefPtr group
= Group::create();
172 _scene
->setCore(group
);
173 _scene
->addChild(torus
);
175 // create the SimpleSceneManager helper
176 _mgr
= SimpleSceneManager::create();
178 // tell the manager what to manage
179 _mgr
->setWindow(gwin
);
180 _mgr
->setRoot(_scene
);
182 // show the whole scene
193 // GLUT callback functions
203 // react to size changes
204 void reshape(int w
, int h
)
210 // react to mouse button presses
211 void mouse(int button
, int state
, int x
, int y
)
214 _mgr
->mouseButtonRelease(button
, x
, y
);
216 _mgr
->mouseButtonPress(button
, x
, y
);
221 // react to mouse motions with pressed buttons
222 void motion(int x
, int y
)
224 _mgr
->mouseMove(x
, y
);
229 void keyboard(unsigned char k
, int x
, int y
)
235 // clean up global variables
243 SceneFileHandler::the()->write(_scene
, "scene.osb.gz", true);
244 printf("wrote scene.osb.gz\n");
251 // setup the GLUT library which handles the windows for us
252 int setupGLUT(int *argc
, char *argv
[])
254 glutInit(argc
, argv
);
255 glutInitDisplayMode(GLUT_RGB
| GLUT_DEPTH
| GLUT_DOUBLE
);
257 int winid
= glutCreateWindow("OpenSG GLSL Geometry Shader");
259 glutReshapeFunc(reshape
);
260 glutDisplayFunc(display
);
261 glutMouseFunc(mouse
);
262 glutMotionFunc(motion
);
263 glutKeyboardFunc(keyboard
);