fixed: auto_ptr -> unique_ptr
[opensg.git] / Examples / Advanced / computeshader2.cpp
blob115945f7331d996175592e30027339071d7cc49e
1 // OpenSG Example: ComputeShader2
2 //
3 // This example shows the most basic usage of the compute shader.
4 // It is a plain translation of the ComplexSceneManager example
5 // found in Examples/CSM/NewShader/Compute/SimpleTex.
6 //
7 // This example differs from the ComputeShader1 only in that a
8 // ShaderProgram object is used instead of providing the shader
9 // source code directly to the ComputeShaderChunk. The variables
10 // are also specified in the ShaderProgram object, which allows the
11 // usage of uniform and shader storage buffer objects. The next example
12 // ComputeShader3 makes use of that.
15 #ifdef OSG_BUILD_ACTIVE
16 // Headers
17 #include <OSGGLUT.h>
18 #include <OSGConfig.h>
19 #include <OSGSimpleGeometry.h>
20 #include <OSGGLUTWindow.h>
21 #include <OSGSimpleSceneManager.h>
22 #include <OSGBaseFunctions.h>
23 #include <OSGTransform.h>
24 #include <OSGGroup.h>
26 // new headers:
27 #include <OSGAlgorithmComputeElement.h>
28 #include <OSGChunkMaterial.h>
29 #include <OSGComputeShaderAlgorithm.h>
30 #include <OSGComputeShaderChunk.h>
31 #include <OSGContainerCollection.h>
32 #include <OSGFieldConnector.h>
33 #include <OSGFrameHandler.h>
34 #include <OSGGeometry.h>
35 #include <OSGImage.h>
36 #include <OSGImageFileHandler.h>
37 #include <OSGMaterialChunk.h>
38 #include <OSGMaterialGroup.h>
39 #include <OSGShaderProgram.h>
40 #include <OSGShaderProgramVariables.h>
41 #include <OSGShaderVariableReal.h>
42 #include <OSGTextureObjChunk.h>
43 #include <OSGTextureEnvChunk.h>
44 #include <OSGTextureImageChunk.h>
45 #include <OSGTime.h>
46 #include <OSGTimeSensor.h>
47 #include <OSGTypedGeoIntegralProperty.h>
48 #include <OSGTypedGeoVectorProperty.h>
49 #include <OSGVRMLScalarInterpolator.h>
50 #else
51 // Headers
52 #include <OpenSG/OSGGLUT.h>
53 #include <OpenSG/OSGConfig.h>
54 #include <OpenSG/OSGSimpleGeometry.h>
55 #include <OpenSG/OSGGLUTWindow.h>
56 #include <OpenSG/OSGSimpleSceneManager.h>
57 #include <OpenSG/OSGBaseFunctions.h>
58 #include <OpenSG/OSGTransform.h>
59 #include <OpenSG/OSGGroup.h>
61 // new headers:
62 #include <OpenSG/OSGAlgorithmComputeElement.h>
63 #include <OpenSG/OSGChunkMaterial.h>
64 #include <OpenSG/OSGComputeShaderAlgorithm.h>
65 #include <OpenSG/OSGComputeShaderChunk.h>
66 #include <OpenSG/OSGContainerCollection.h>
67 #include <OpenSG/OSGFieldConnector.h>
68 #include <OpenSG/OSGFrameHandler.h>
69 #include <OpenSG/OSGGeometry.h>
70 #include <OpenSG/OSGImage.h>
71 #include <OpenSG/OSGImageFileHandler.h>
72 #include <OpenSG/OSGMaterialChunk.h>
73 #include <OpenSG/OSGMaterialGroup.h>
74 #include <OpenSG/OSGShaderProgram.h>
75 #include <OpenSG/OSGShaderProgramVariables.h>
76 #include <OpenSG/OSGShaderVariableReal.h>
77 #include <OpenSG/OSGTextureObjChunk.h>
78 #include <OpenSG/OSGTextureEnvChunk.h>
79 #include <OpenSG/OSGTextureImageChunk.h>
80 #include <OpenSG/OSGTime.h>
81 #include <OpenSG/OSGTimeSensor.h>
82 #include <OpenSG/OSGTypedGeoIntegralProperty.h>
83 #include <OpenSG/OSGTypedGeoVectorProperty.h>
84 #include <OpenSG/OSGVRMLScalarInterpolator.h>
85 #endif
87 OSG::SimpleSceneManagerRefPtr mgr = NULL;
89 std::string get_cp_program();
91 OSG::NodeTransitPtr createPlane(OSG::TextureObjChunk* texObjChunk)
93 OSG::MaterialChunkRefPtr matChunk = OSG::MaterialChunk::create();
94 matChunk->setDiffuse(OSG::Color4f(0.f, 0.f, 0.f, 1.f));
96 OSG::TextureEnvChunkRefPtr texEnvChunk = OSG::TextureEnvChunk::create();
97 texEnvChunk->setEnvMode(GL_REPLACE);
99 OSG::ChunkMaterialRefPtr chunkMaterial = OSG::ChunkMaterial::create();
100 chunkMaterial->addChunk(texObjChunk, 0);
101 chunkMaterial->addChunk(texEnvChunk);
102 chunkMaterial->addChunk(matChunk);
105 OSG::MaterialGroupRefPtr matGroup = OSG::MaterialGroup::create();
106 matGroup->setMaterial(chunkMaterial);
108 OSG::NodeRefPtr plane = OSG::makeNodeFor(matGroup);
110 OSG::GeometryRefPtr geometry = OSG::Geometry::create();
111 geometry->setDlistCache(false);
112 geometry->setUseVAO(true);
113 geometry->setUseAttribCalls(true);
115 OSG::NodeRefPtr geomNode = OSG::makeNodeFor(geometry);
117 OSG::GeoUInt8PropertyRefPtr types = OSG::GeoUInt8Property ::create();
118 OSG::GeoUInt32PropertyRefPtr lengths = OSG::GeoUInt32Property::create();
119 OSG::GeoPnt3fPropertyRefPtr vertices = OSG::GeoPnt3fProperty ::create();
120 OSG::GeoVec3fPropertyRefPtr normals = OSG::GeoVec3fProperty ::create();
121 OSG::GeoColor3fPropertyRefPtr colors = OSG::GeoColor3fProperty::create();
122 OSG::GeoVec2fPropertyRefPtr textures = OSG::GeoVec2fProperty ::create();
123 OSG::GeoUInt32PropertyRefPtr indices = OSG::GeoUInt32Property::create();
125 types ->setUseVBO(true);
126 lengths ->setUseVBO(true);
127 indices ->setUseVBO(true);
128 vertices->setUseVBO(true);
129 normals ->setUseVBO(true);
130 colors ->setUseVBO(true);
131 textures->setUseVBO(true);
133 types ->setUsage(OSG::GeoProperty::UsageSystemSet);
134 lengths ->setUsage(OSG::GeoProperty::UsageSystemSet);
135 indices ->setUsage(OSG::GeoProperty::UsageSystemSet);
136 vertices->setUsage(OSG::GeoProperty::UsageSystemSet);
137 normals ->setUsage(OSG::GeoProperty::UsageSystemSet);
138 colors ->setUsage(OSG::GeoProperty::UsageSystemSet);
139 textures->setUsage(OSG::GeoProperty::UsageSystemSet);
141 types ->push_back(4);
142 lengths->push_back(6);
144 indices->push_back(0);
145 indices->push_back(1);
146 indices->push_back(2);
147 indices->push_back(0);
148 indices->push_back(2);
149 indices->push_back(3);
151 vertices->push_back(OSG::Pnt3f(-1.f,-1.f,-1.f));
152 vertices->push_back(OSG::Pnt3f( 1.f,-1.f,-1.f));
153 vertices->push_back(OSG::Pnt3f( 1.f, 1.f,-3.f));
154 vertices->push_back(OSG::Pnt3f(-1.f, 1.f,-3.f));
156 normals->push_back(OSG::Vec3f(0.f, 0.f, 1.f));
157 normals->push_back(OSG::Vec3f(0.f, 0.f, 1.f));
158 normals->push_back(OSG::Vec3f(0.f, 0.f, 1.f));
159 normals->push_back(OSG::Vec3f(0.f, 0.f, 1.f));
161 colors->push_back(OSG::Color3f(0.f, 1.f, 0.f));
163 textures->push_back(OSG::Vec2i(0,0));
164 textures->push_back(OSG::Vec2i(1,0));
165 textures->push_back(OSG::Vec2i(1,1));
166 textures->push_back(OSG::Vec2i(0,1));
168 geometry->setTypes (types);
169 geometry->setLengths (lengths);
170 geometry->setIndices (indices);
171 geometry->setPositions(vertices);
172 geometry->setNormals (normals);
173 geometry->setColors (colors);
174 geometry->setTexCoords(textures);
176 plane->addChild(geomNode);
178 return OSG::NodeTransitPtr(plane);
181 OSG::NodeTransitPtr createScene()
183 OSG::ImageRefPtr image = OSG::ImageFileHandler::the()->read("Examples/CSM/Models/Textures/Earth512.png");
185 OSG::TextureObjChunkRefPtr texObjChunk = OSG::TextureObjChunk::create();
186 texObjChunk->setInternalFormat(GL_RGBA32F);
187 texObjChunk->setMinFilter(GL_LINEAR);
188 texObjChunk->setMagFilter(GL_LINEAR);
189 texObjChunk->setImage(image);
191 OSG::NodeRefPtr planeNode = createPlane(texObjChunk);
193 OSG::AlgorithmComputeElementRefPtr algoCompElement = OSG::AlgorithmComputeElement::create();
194 OSG::NodeRefPtr computeNode = OSG::makeNodeFor(algoCompElement);
195 computeNode->addChild(planeNode);
197 OSG::ComputeShaderAlgorithmRefPtr compShaderAlgo = OSG::ComputeShaderAlgorithm::create();
198 algoCompElement->setAlgorithm(compShaderAlgo);
200 OSG::TextureImageChunkRefPtr texImgChunk = OSG::TextureImageChunk::create();
201 texImgChunk->setTexture(texObjChunk);
202 texImgChunk->setAccess(GL_WRITE_ONLY);
203 texImgChunk->setFormat(GL_RGBA32F);
205 OSG::ShaderProgramRefPtr compShader = OSG::ShaderProgram::create();
206 compShader->setShaderType(GL_COMPUTE_SHADER);
207 compShader->setProgram(get_cp_program());
208 compShader->addUniformVariable("destTex", 0);
209 compShader->addUniformVariable("roll", 0.f);
211 OSG::ComputeShaderChunkRefPtr compShaderChunk = OSG::ComputeShaderChunk::create();
212 compShaderChunk->addComputeShader(compShader);
213 compShaderChunk->setVariables(compShader->getVariables());
215 compShaderAlgo->setComputeShader(compShaderChunk);
216 compShaderAlgo->pushToTextureImages(texImgChunk);
217 compShaderAlgo->setDispatchConfig(OSG::Vec3i(32, 32, 1));
219 OSG::NodeRefPtr scene = OSG::makeCoredNode<OSG::Group>();
220 scene->addChild(computeNode);
222 OSG::TimeSensorRefPtr sceneTimer = OSG::TimeSensor::create();
223 sceneTimer->setLoop(true);
224 sceneTimer->setCycleInterval(10);
226 OSG::VRMLScalarInterpolatorRefPtr rollInter = OSG::VRMLScalarInterpolator::create();
227 rollInter->editMFKeyValue()->push_back(0.f);
228 rollInter->editMFKeyValue()->push_back(10.24f);
230 rollInter->editMFKey()->push_back(0.f);
231 rollInter->editMFKey()->push_back(1.f);
233 const OSG::ShaderVariableReal* varRealRoll = dynamic_cast<const OSG::ShaderVariableReal*>(compShader->getVariables()->getVariable("roll"));
235 addConnection(sceneTimer, "fraction", rollInter, "inValue");
236 addConnection(rollInter, "outValue", const_cast<OSG::ShaderVariableReal*>(varRealRoll), "value");
238 OSG::ContainerCollectionRefPtr containerCollection = OSG::ContainerCollection::create();
240 containerCollection->addContainer(rollInter);
241 containerCollection->addContainer(sceneTimer);
243 scene->addAttachment(containerCollection);
245 return OSG::NodeTransitPtr(scene);
249 // forward declaration so we can have the interesting stuff upfront
251 int setupGLUT(int *argc, char *argv[]);
252 void releaseGLUT();
253 void print_help();
256 // Initialize GLUT & OpenSG and set up the scene
258 int main(int argc, char **argv)
260 OSG::preloadSharedObject("OSGImageFileIO");
262 // OSG init
263 OSG::osgInit(argc,argv);
265 // GLUT init
266 int winid = setupGLUT(&argc, argv);
268 print_help();
270 // open a new scope, because the pointers below should go out of scope
271 // before entering glutMainLoop.
272 // Otherwise OpenSG will complain about objects being alive after shutdown.
274 // the connection between GLUT and OpenSG
275 OSG::GLUTWindowRefPtr gwin = OSG::GLUTWindow::create();
276 gwin->setGlutId(winid);
277 gwin->init();
279 // create the SimpleSceneManager helper
280 mgr = OSG::SimpleSceneManager::create();
281 mgr->setWindow(gwin);
283 // The scene
284 OSG::NodeRefPtr scene = createScene();
286 mgr->setRoot(scene);
288 OSG::commitChanges();
290 // show the whole scene
291 mgr->showAll();
294 // GLUT main loop
295 glutMainLoop();
297 return 0;
301 // GLUT callback functions
305 // redraw the window
307 void display(void)
309 OSG::FrameHandler::the()->frame();
311 OSG::commitChanges();
313 mgr->redraw();
316 // react to size changes
318 void reshape(int w, int h)
320 mgr->resize(w, h);
321 glutPostRedisplay();
325 // react to mouse button presses
327 void mouse(int button, int state, int x, int y)
329 if (state)
330 mgr->mouseButtonRelease(button, x, y);
331 else
332 mgr->mouseButtonPress(button, x, y);
334 glutPostRedisplay();
338 // react to mouse motions with pressed buttons
340 void motion(int x, int y)
342 mgr->mouseMove(x, y);
343 glutPostRedisplay();
347 // react to keys
349 void keyboard(unsigned char k, int x, int y)
351 switch(k)
353 case 27: // ESC
355 // clean up global variables
356 mgr = NULL;
358 releaseGLUT();
360 OSG::osgExit();
361 exit(0);
363 break;
368 // setup the GLUT library which handles the windows for us
370 int setupGLUT(int *argc, char *argv[])
372 glutInit(argc, argv);
373 glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE);
374 glutInitWindowSize(1000, 800);
376 int winid = glutCreateWindow("OpenSG");
378 glutReshapeFunc(reshape);
379 glutDisplayFunc(display);
380 glutMouseFunc(mouse);
381 glutMotionFunc(motion);
382 glutKeyboardFunc(keyboard);
384 // call the redraw function whenever there's nothing else to do
385 glutIdleFunc(display);
387 return winid;
390 void releaseGLUT()
392 glutReshapeFunc(NULL);
393 glutDisplayFunc(NULL);
394 glutMouseFunc(NULL);
395 glutMotionFunc(NULL);
396 glutKeyboardFunc(NULL);
397 glutIdleFunc(NULL);
400 void print_help()
402 std::cout << "Esc : quit example" << std::endl;
406 std::string get_cp_program()
408 using namespace std;
410 stringstream ost;
412 ost << "#version 440 compatibility"
413 << endl << ""
414 << endl << "uniform float roll;"
415 << endl << "uniform writeonly image2D destTex;"
416 << endl << ""
417 << endl << "layout (local_size_x = 16, local_size_y = 16) in;"
418 << endl << ""
419 << endl << "void main()"
420 << endl << "{"
421 << endl << " ivec2 storePos = ivec2( gl_GlobalInvocationID.xy );"
422 << endl << " float localCoef = length( vec2( ivec2(gl_LocalInvocationID.xy) - 8 ) / 8.0 );"
423 << endl << " float globalCoef = sin( float(gl_WorkGroupID.x + gl_WorkGroupID.y) * 0.1 + roll ) * 0.5;"
424 << endl << ""
425 << endl << " imageStore(destTex, storePos, vec4(1.0 - globalCoef * localCoef, 0.0, 0.0, 0.0));"
426 << endl << "}"
427 << endl << ""
428 << endl;
430 return ost.str();