fixed: auto_ptr -> unique_ptr
[opensg.git] / Source / System / State / Shader / Chunks / testSHLSharedParameters_shaderprog.cpp
blob178b7c9d7d95ac82ca194033a7c959439956f753
1 // OpenSG example: testSHL
2 //
3 // Demonstrates the use of the SHLChunk
4 // Ok this creates 1 CGChunk with different parameter sets for each geometry.
6 // Headers
7 #include "OSGGLUT.h"
8 #include "OSGConfig.h"
9 #include "OSGSimpleGeometry.h"
10 #include "OSGGLUT.h"
11 #include "OSGGLUTWindow.h"
12 #include "OSGSimpleSceneManager.h"
13 #include "OSGAction.h"
14 #include "OSGSceneFileHandler.h"
15 #include "OSGBaseFunctions.h"
17 #include "OSGGradientBackground.h"
18 #include "OSGNode.h"
19 #include "OSGGroup.h"
20 #include "OSGTransform.h"
21 #include "OSGPointLight.h"
22 #include "OSGMaterialGroup.h"
24 #include "OSGImage.h"
25 #include "OSGChunkMaterial.h"
26 #include "OSGMaterialChunk.h"
27 #include "OSGShaderProgramChunk.h"
28 #include "OSGShaderProgramVariableChunk.h"
29 #include "OSGShaderProgram.h"
31 // vertex shader program for
32 static std::string _vp_program =
33 "varying vec3 DiffuseColor;\n"
34 "varying vec3 SpecularColor;\n"
35 "\n"
36 "void main(void)\n"
37 "{\n"
38 " vec3 LightColor = vec3(1.0);\n"
39 " vec3 Specular = vec3(1.0);\n"
40 " vec3 Ambient = vec3(0.2);\n"
41 " float Kd = 0.3;\n"
42 "\n"
43 " vec3 LightPosition = gl_LightSource[0].position.xyz;\n"
44 "\n"
45 " vec3 ecPosition = vec3(gl_ModelViewMatrix * gl_Vertex);\n"
46 "\n"
47 " vec3 tnorm = normalize(gl_NormalMatrix * gl_Normal);\n"
48 "\n"
49 " vec3 lightVec = normalize(LightPosition - ecPosition);\n"
50 "\n"
51 " vec3 hvec = normalize(lightVec - ecPosition);\n"
52 "\n"
53 " float spec = clamp(dot(hvec, tnorm), 0.0, 1.0);\n"
54 " spec = pow(spec, 16.0);\n"
55 "\n"
56 " DiffuseColor = LightColor * vec3(Kd * dot(lightVec, tnorm));\n"
57 " DiffuseColor = clamp(Ambient + DiffuseColor, 0.0, 1.0);\n"
58 " SpecularColor = clamp((LightColor * Specular * spec), 0.0 ,1.0);\n"
59 "\n"
60 " gl_TexCoord[0] = gl_MultiTexCoord0;\n"
61 " gl_Position = ftransform();\n"
62 "}\n";
65 // fragment shader program for
66 static std::string _fp_program =
67 "varying vec3 DiffuseColor;\n"
68 "varying vec3 SpecularColor;\n"
69 "\n"
70 "uniform vec2 Scale;\n"
71 "uniform vec2 Threshold;\n"
72 "uniform vec3 SurfaceColor;\n"
73 "\n"
74 "void main (void)\n"
75 "{\n"
76 " float ss = fract(gl_TexCoord[0].s * Scale.s);\n"
77 " float tt = fract(gl_TexCoord[0].t * Scale.t);\n"
78 "\n"
79 " if ((ss > Threshold.s) && (tt > Threshold.t))\n"
80 " discard;\n"
81 "\n"
82 " vec3 finalColor = SurfaceColor * DiffuseColor + SpecularColor;\n"
83 " gl_FragColor = vec4(finalColor, 1.0);\n"
84 "}\n";
88 // ------------------- global vars ----------------------
90 // The SimpleSceneManager to manage simple applications
91 static OSG::SimpleSceneManagerRefPtr _mgr;
92 // The scene
93 static OSG::NodeRecPtr _scene;
95 static OSG::ShaderProgramVariableChunkRecPtr _shlparameter = NULL;
98 // forward declaration so we can have the interesting stuff upfront
99 int setupGLUT( int *argc, char *argv[] );
101 // Initialize GLUT & OpenSG and set up the scene
102 int doMain(int argc, char **argv)
104 // OSG init
105 OSG::osgInit(argc,argv);
107 // GLUT init
108 int winid = setupGLUT(&argc, argv);
110 // the connection between GLUT and OpenSG
111 OSG::GLUTWindowUnrecPtr gwin = OSG::GLUTWindow::create();
113 gwin->setGlutId(winid);
114 gwin->setSize( 800, 800 );
115 gwin->init();
117 // create root node
118 _scene = OSG::makeCoredNode<OSG::Group>();
120 OSG::GeometryUnrecPtr geo = OSG::makeBoxGeo(0.5, 0.5, 0.5, 1, 1, 1);
122 // share the chunk
123 OSG::ShaderProgramChunkUnrecPtr shl = OSG::ShaderProgramChunk::create();
125 OSG::ShaderProgramUnrecPtr shl_vp =
126 OSG::ShaderProgram::createVertexShader();
128 shl_vp->setProgram(_vp_program);
130 shl->addShader(shl_vp);
133 OSG::ShaderProgramUnrecPtr shl_fp =
134 OSG::ShaderProgram::createFragmentShader();
136 shl_fp->setProgram(_fp_program);
138 shl->addShader(shl_fp);
140 // These parameters are the same for all geometries so we
141 // keep them in here.
142 shl_fp->addUniformVariable("Scale", OSG::Vec2f(20.0f, 20.0f));
143 shl_fp->addUniformVariable("Threshold", OSG::Vec2f(0.7f, 0.7f));
145 OSG::Int32 size = 4;
147 // start color
148 OSG::Vec3f sc(0.0, 0.0, 0.0);
150 // end color
151 OSG::Vec3f ec(1.0, 1.0, 1.0);
153 OSG::Real32 sr = (ec[0] - sc[0]) / OSG::Real32((size*2));
154 OSG::Real32 sg = (ec[1] - sc[1]) / OSG::Real32((size*2));
155 OSG::Real32 sb = (ec[2] - sc[2]) / OSG::Real32((size*2));
157 OSG::Vec3f color(sc);
159 OSG::Int32 x = - size;
160 OSG::Int32 y = - size;
161 OSG::Int32 z = - size;
163 OSG::UInt32 iterations = size*2 * size*2 * size*2;
165 printf("Creating %u cubes ...\n", iterations);
166 for(OSG::UInt32 i=0;i<iterations;++i)
168 OSG::ChunkMaterialUnrecPtr cmat = OSG::ChunkMaterial::create();
170 // ok use one SHLChunk and n SHLParameterChunks
171 // Assing a different "SurfaceColor" parameter to each geometry.
172 OSG::ShaderProgramVariableChunkUnrecPtr shlparameter =
173 OSG::ShaderProgramVariableChunk::create();
175 // shlparameter->setSHLChunk(shl);
176 shlparameter->addUniformVariable("SurfaceColor", color);
178 _shlparameter = shlparameter;
180 cmat->addChunk(shlparameter);
182 cmat->addChunk(shl);
184 OSG::TransformUnrecPtr trans;
185 OSG::NodeUnrecPtr trans_node =
186 OSG::makeCoredNode<OSG::Transform>(&trans);
188 trans->editMatrix().setTranslate(OSG::Real32(x),
189 OSG::Real32(y),
190 OSG::Real32(z));
192 OSG::MaterialGroupUnrecPtr mg;
194 OSG::NodeUnrecPtr mg_node = OSG::makeCoredNode<OSG::MaterialGroup>(&mg);
196 mg->setMaterial(cmat);
198 OSG::NodeUnrecPtr geonode = OSG::Node::create();
200 geonode->setCore(geo);
202 mg_node->addChild(geonode);
204 trans_node->addChild(mg_node);
206 // add to scene
207 _scene->addChild(trans_node);
209 // ----
210 ++x;
211 color[0] += sr;
213 if(x == size)
215 x = - size;
216 ++y;
217 color[0] = sc[0];
218 color[1] += sg;
219 if(y == size)
221 y = - size;
222 ++z;
223 color[1] = sc[1];
224 color[2] += sb;
230 // create the SimpleSceneManager helper
231 _mgr = OSG::SimpleSceneManager::create();
233 // tell the manager what to manage
234 _mgr->setWindow(gwin );
235 _mgr->setRoot(_scene);
237 // show the whole scene
238 _mgr->showAll();
240 // create a gradient background.
241 OSG::GradientBackgroundUnrecPtr gback = OSG::GradientBackground::create();
243 gback->clearLines();
244 gback->addLine(OSG::Color3f(0.7f, 0.7f, 0.8f), 0);
245 gback->addLine(OSG::Color3f(0.0f, 0.1f, 0.3f), 1);
247 OSG::Window *win = _mgr->getWindow();
249 for(unsigned int i=0;i<win->getMFPort()->size();++i)
251 OSG::Viewport *vp = win->getPort(i);
252 vp->setBackground(gback);
255 return 0;
258 // Initialize GLUT & OpenSG and set up the scene
259 int main(int argc, char **argv)
261 if(doMain(argc, argv) != 0)
262 return 1;
264 // GLUT main loop
265 glutMainLoop();
267 return 0;
271 // GLUT callback functions
274 // redraw the window
275 void display(void)
277 #if 0
278 OSG::Real64 t = OSG::getSystemTime();
279 #endif
280 // render scene
281 _mgr->redraw();
283 #if 0
284 t = OSG::getSystemTime() - t;
285 if(t > 0.0)
286 printf("fps: %f\r", 1.0f / OSG::Real32(t));
287 else
288 printf("fps: very fast ...\r");
289 #endif
292 // react to size changes
293 void reshape(int w, int h)
295 _mgr->resize(w, h);
296 glutPostRedisplay();
299 // react to mouse button presses
300 void mouse(int button, int state, int x, int y)
302 if (state)
303 _mgr->mouseButtonRelease(button, x, y);
304 else
305 _mgr->mouseButtonPress(button, x, y);
307 glutPostRedisplay();
310 // react to mouse motions with pressed buttons
311 void motion(int x, int y)
313 _mgr->mouseMove(x, y);
314 glutPostRedisplay();
317 // react to keys
318 void keyboard(unsigned char k, int x, int y)
320 switch(k)
322 case 27:
323 case 'q':
325 _scene = NULL;
326 _shlparameter = NULL;
328 _mgr = NULL;
330 exit(1);
331 break;
332 case 'w':
333 OSG::SceneFileHandler::the()->write(_scene, "scene.osb.gz", true);
334 printf("wrote scene.osb.gz\n");
335 break;
336 case 'c':
337 if(_shlparameter != NULL)
339 _shlparameter->updateUniformVariable(
340 "SurfaceColor",
341 OSG::Vec3f(1.0f, 1.0f, 1.0f));
343 break;
344 case 'b':
345 if(_shlparameter != NULL)
347 _shlparameter->updateUniformVariable(
348 "SurfaceColor",
349 OSG::Vec3f(0.0f, 0.0f, 0.0f));
351 break;
352 case 'r':
353 if(_shlparameter != NULL)
355 _shlparameter->subUniformVariable("SurfaceColor");
356 // _shlparameter->updateUniformVariable("SurfaceColor",
357 // Vec3f(1.0f, 1.0f, 1.0f));
359 break;
360 case 'a':
361 if(_shlparameter != NULL)
363 _shlparameter->addUniformVariable("SurfaceColor",
364 OSG::Vec3f(1.0f, 1.0f, 1.0f));
366 break;
369 glutPostRedisplay();
372 // setup the GLUT library which handles the windows for us
373 int setupGLUT(int *argc, char *argv[])
375 glutInit(argc, argv);
376 glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE);
378 int winid = glutCreateWindow("OpenSG SHL Shader");
380 glutReshapeFunc(reshape);
381 glutDisplayFunc(display);
382 glutMouseFunc(mouse);
383 glutMotionFunc(motion);
384 glutKeyboardFunc(keyboard);
386 glutIdleFunc(display);
388 return winid;