fixed: auto_ptr -> unique_ptr
[opensg.git] / Examples / Simple / geometryshader.cpp
blob05bb05d0765f4ef297e5148602b2ad49bca8c634
1 // OpenSG GLSL shader example: Geometry Shader
2 //
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
8 // Headers
9 #include <OSGConfig.h>
10 #include <OSGSimpleGeometry.h>
11 #include <OSGGLUT.h>
12 #include <OSGGLEXT.h>
13 #include <OSGGLUTWindow.h>
14 #include <OSGSimpleSceneManager.h>
15 #include <OSGAction.h>
16 #include <OSGSceneFileHandler.h>
17 #include <OSGBaseFunctions.h>
19 #include <OSGNode.h>
20 #include <OSGGroup.h>
21 #include <OSGTransform.h>
22 #include <OSGPointLight.h>
24 #include <OSGImage.h>
25 #include <OSGChunkMaterial.h>
26 #include <OSGMaterialChunk.h>
27 #include <OSGTextureChunk.h>
28 #include <OSGSHLChunk.h>
29 #else
30 // Headers
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>
51 #endif
55 // ------------------- global vars ----------------------
57 // The SimpleSceneManager to manage simple applications
58 SimpleSceneManagerRefPtr _mgr;
59 // The scene
60 NodeRefPtr _scene;
62 // forward declaration so we can have the interesting stuff upfront
63 int setupGLUT( int *argc, char *argv[] );
65 static std::string _vertex_shader =
66 "void main(void)\n"
67 "{\n"
68 " gl_Position = gl_Vertex;\n"
69 " gl_TexCoord[0] = vec4(abs(gl_Normal), 0.0);\n"
70 "}\n"
71 "\n";
73 static std::string _fragment_shader =
74 "void main (void)\n"
75 "{\n"
76 " gl_FragColor = gl_Color;\n"
77 "\n"
78 "}\n";
80 // ok we create some triangles to draw the face normals.
81 static std::string _geometry_shader =
82 "#version 120\n"
83 "#extension GL_EXT_geometry_shader4 : enable\n"
84 "\n"
85 "void main(void)\n"
86 "{\n"
87 " vec4 v1 = gl_PositionIn[0];\n"
88 " vec4 v2 = gl_PositionIn[1];\n"
89 " vec4 v3 = gl_PositionIn[2];\n"
90 "\n"
91 " vec4 l1 = v2 - v1;\n"
92 " vec4 l2 = v3 - v1;\n"
93 "\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"
97 " EmitVertex();\n"
98 " gl_Position = gl_ModelViewProjectionMatrix * v2;\n"
99 " gl_FrontColor = vec4(0.0, 1.0, 0.0, 0.0);\n"
100 " EmitVertex();\n"
101 " gl_Position = gl_ModelViewProjectionMatrix * v3;\n"
102 " gl_FrontColor = vec4(0.0, 1.0, 0.0, 0.0);\n"
103 " EmitVertex();\n"
104 " EndPrimitive();\n"
105 "\n"
106 " vec3 l1n = l1.xyz;\n"
107 " vec3 l2n = l2.xyz;\n"
108 "\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"
115 " EmitVertex();\n"
116 " gl_FrontColor = gl_TexCoordIn[0][0];\n"
117 " gl_Position = gl_ModelViewProjectionMatrix * (middle + 0.1 * vec4(N, 0.0));\n"
118 " EmitVertex();\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"
121 " EmitVertex();\n"
122 " EndPrimitive();\n"
123 "\n"
124 "}\n";
126 // Initialize GLUT & OpenSG and set up the scene
127 int main(int argc, char **argv)
129 // OSG init
130 osgInit(argc,argv);
132 // GLUT init
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 );
143 gwin->init();
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);
158 cmat->addChunk(shl);
160 // create root node
161 _scene = Node::create();
163 // create torus
164 GeometryRefPtr geo = makeTorusGeo(.8, 1.8, 32, 32);
165 geo->setMaterial(cmat);
167 NodeRefPtr torus = Node::create();
168 torus->setCore(geo);
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
183 _mgr->showAll();
186 // GLUT main loop
187 glutMainLoop();
189 return 0;
193 // GLUT callback functions
196 // redraw the window
197 void display(void)
199 // render scene
200 _mgr->redraw();
203 // react to size changes
204 void reshape(int w, int h)
206 _mgr->resize(w, h);
207 glutPostRedisplay();
210 // react to mouse button presses
211 void mouse(int button, int state, int x, int y)
213 if (state)
214 _mgr->mouseButtonRelease(button, x, y);
215 else
216 _mgr->mouseButtonPress(button, x, y);
218 glutPostRedisplay();
221 // react to mouse motions with pressed buttons
222 void motion(int x, int y)
224 _mgr->mouseMove(x, y);
225 glutPostRedisplay();
228 // react to keys
229 void keyboard(unsigned char k, int x, int y)
231 switch(k)
233 case 27:
234 case 'q':
235 // clean up global variables
236 _mgr = NULL;
237 _scene = NULL;
239 osgExit();
240 exit(1);
241 break;
242 case 'w':
243 SceneFileHandler::the()->write(_scene, "scene.osb.gz", true);
244 printf("wrote scene.osb.gz\n");
245 break;
248 glutPostRedisplay();
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);
265 return winid;