fixed: compile issue
[opensg.git] / Examples / Advanced / computeshader1.cpp
blobba6cb595c1503d370d34201e46c3e9e4b605a69b
1 // OpenSG Example: ComputeShader1
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 //
8 #ifdef OSG_BUILD_ACTIVE
9 // Headers
10 #include <OSGGLUT.h>
11 #include <OSGConfig.h>
12 #include <OSGSimpleGeometry.h>
13 #include <OSGGLUTWindow.h>
14 #include <OSGSimpleSceneManager.h>
15 #include <OSGBaseFunctions.h>
16 #include <OSGTransform.h>
17 #include <OSGGroup.h>
19 // new headers:
20 #include <OSGAlgorithmComputeElement.h>
21 #include <OSGChunkMaterial.h>
22 #include <OSGComputeShaderAlgorithm.h>
23 #include <OSGComputeShaderChunk.h>
24 #include <OSGContainerCollection.h>
25 #include <OSGFieldConnector.h>
26 #include <OSGFrameHandler.h>
27 #include <OSGGeometry.h>
28 #include <OSGImage.h>
29 #include <OSGImageFileHandler.h>
30 #include <OSGMaterialChunk.h>
31 #include <OSGMaterialGroup.h>
32 #include <OSGShaderProgramVariables.h>
33 #include <OSGShaderVariableReal.h>
34 #include <OSGTextureObjChunk.h>
35 #include <OSGTextureEnvChunk.h>
36 #include <OSGTextureImageChunk.h>
37 #include <OSGTime.h>
38 #include <OSGTimeSensor.h>
39 #include <OSGTypedGeoIntegralProperty.h>
40 #include <OSGTypedGeoVectorProperty.h>
41 #include <OSGVRMLScalarInterpolator.h>
42 #else
43 // Headers
44 #include <OpenSG/OSGGLUT.h>
45 #include <OpenSG/OSGConfig.h>
46 #include <OpenSG/OSGSimpleGeometry.h>
47 #include <OpenSG/OSGGLUTWindow.h>
48 #include <OpenSG/OSGSimpleSceneManager.h>
49 #include <OpenSG/OSGBaseFunctions.h>
50 #include <OpenSG/OSGTransform.h>
51 #include <OpenSG/OSGGroup.h>
53 // new headers:
54 #include <OpenSG/OSGAlgorithmComputeElement.h>
55 #include <OpenSG/OSGChunkMaterial.h>
56 #include <OpenSG/OSGComputeShaderAlgorithm.h>
57 #include <OpenSG/OSGComputeShaderChunk.h>
58 #include <OpenSG/OSGContainerCollection.h>
59 #include <OpenSG/OSGFieldConnector.h>
60 #include <OpenSG/OSGFrameHandler.h>
61 #include <OpenSG/OSGGeometry.h>
62 #include <OpenSG/OSGImage.h>
63 #include <OpenSG/OSGImageFileHandler.h>
64 #include <OpenSG/OSGMaterialChunk.h>
65 #include <OpenSG/OSGMaterialGroup.h>
66 #include <OpenSG/OSGShaderProgramVariables.h>
67 #include <OpenSG/OSGShaderVariableReal.h>
68 #include <OpenSG/OSGTextureObjChunk.h>
69 #include <OpenSG/OSGTextureEnvChunk.h>
70 #include <OpenSG/OSGTextureImageChunk.h>
71 #include <OpenSG/OSGTime.h>
72 #include <OpenSG/OSGTimeSensor.h>
73 #include <OpenSG/OSGTypedGeoIntegralProperty.h>
74 #include <OpenSG/OSGTypedGeoVectorProperty.h>
75 #include <OpenSG/OSGVRMLScalarInterpolator.h>
76 #endif
78 OSG::SimpleSceneManagerRefPtr mgr = NULL;
80 std::string get_cp_program();
82 OSG::NodeTransitPtr createPlane(OSG::TextureObjChunk* texObjChunk)
84 OSG::MaterialChunkRefPtr matChunk = OSG::MaterialChunk::create();
85 matChunk->setDiffuse(OSG::Color4f(0.f, 0.f, 0.f, 1.f));
87 OSG::TextureEnvChunkRefPtr texEnvChunk = OSG::TextureEnvChunk::create();
88 texEnvChunk->setEnvMode(GL_REPLACE);
90 OSG::ChunkMaterialRefPtr chunkMaterial = OSG::ChunkMaterial::create();
91 chunkMaterial->addChunk(texObjChunk, 0);
92 chunkMaterial->addChunk(texEnvChunk);
93 chunkMaterial->addChunk(matChunk);
96 OSG::MaterialGroupRefPtr matGroup = OSG::MaterialGroup::create();
97 matGroup->setMaterial(chunkMaterial);
99 OSG::NodeRefPtr plane = OSG::makeNodeFor(matGroup);
101 OSG::GeometryRefPtr geometry = OSG::Geometry::create();
102 geometry->setDlistCache(false);
103 geometry->setUseVAO(true);
104 geometry->setUseAttribCalls(true);
106 OSG::NodeRefPtr geomNode = OSG::makeNodeFor(geometry);
108 OSG::GeoUInt8PropertyRefPtr types = OSG::GeoUInt8Property ::create();
109 OSG::GeoUInt32PropertyRefPtr lengths = OSG::GeoUInt32Property::create();
110 OSG::GeoPnt3fPropertyRefPtr vertices = OSG::GeoPnt3fProperty ::create();
111 OSG::GeoVec3fPropertyRefPtr normals = OSG::GeoVec3fProperty ::create();
112 OSG::GeoColor3fPropertyRefPtr colors = OSG::GeoColor3fProperty::create();
113 OSG::GeoVec2fPropertyRefPtr textures = OSG::GeoVec2fProperty ::create();
114 OSG::GeoUInt32PropertyRefPtr indices = OSG::GeoUInt32Property::create();
116 types ->setUseVBO(true);
117 lengths ->setUseVBO(true);
118 indices ->setUseVBO(true);
119 vertices->setUseVBO(true);
120 normals ->setUseVBO(true);
121 colors ->setUseVBO(true);
122 textures->setUseVBO(true);
124 types ->setUsage(OSG::GeoProperty::UsageSystemSet);
125 lengths ->setUsage(OSG::GeoProperty::UsageSystemSet);
126 indices ->setUsage(OSG::GeoProperty::UsageSystemSet);
127 vertices->setUsage(OSG::GeoProperty::UsageSystemSet);
128 normals ->setUsage(OSG::GeoProperty::UsageSystemSet);
129 colors ->setUsage(OSG::GeoProperty::UsageSystemSet);
130 textures->setUsage(OSG::GeoProperty::UsageSystemSet);
132 types ->push_back(4);
133 lengths->push_back(6);
135 indices->push_back(0);
136 indices->push_back(1);
137 indices->push_back(2);
138 indices->push_back(0);
139 indices->push_back(2);
140 indices->push_back(3);
142 vertices->push_back(OSG::Pnt3f(-1.f,-1.f,-1.f));
143 vertices->push_back(OSG::Pnt3f( 1.f,-1.f,-1.f));
144 vertices->push_back(OSG::Pnt3f( 1.f, 1.f,-3.f));
145 vertices->push_back(OSG::Pnt3f(-1.f, 1.f,-3.f));
147 normals->push_back(OSG::Vec3f(0.f, 0.f, 1.f));
148 normals->push_back(OSG::Vec3f(0.f, 0.f, 1.f));
149 normals->push_back(OSG::Vec3f(0.f, 0.f, 1.f));
150 normals->push_back(OSG::Vec3f(0.f, 0.f, 1.f));
152 colors->push_back(OSG::Color3f(0.f, 1.f, 0.f));
154 textures->push_back(OSG::Vec2i(0,0));
155 textures->push_back(OSG::Vec2i(1,0));
156 textures->push_back(OSG::Vec2i(1,1));
157 textures->push_back(OSG::Vec2i(0,1));
159 geometry->setTypes (types);
160 geometry->setLengths (lengths);
161 geometry->setIndices (indices);
162 geometry->setPositions(vertices);
163 geometry->setNormals (normals);
164 geometry->setColors (colors);
165 geometry->setTexCoords(textures);
167 plane->addChild(geomNode);
169 return OSG::NodeTransitPtr(plane);
172 OSG::NodeTransitPtr createScene()
174 OSG::ImageRefPtr image = OSG::ImageFileHandler::the()->read("Examples/CSM/Models/Textures/Earth512.png");
176 OSG::TextureObjChunkRefPtr texObjChunk = OSG::TextureObjChunk::create();
177 texObjChunk->setInternalFormat(GL_RGBA32F);
178 texObjChunk->setMinFilter(GL_LINEAR);
179 texObjChunk->setMagFilter(GL_LINEAR);
180 texObjChunk->setImage(image);
182 OSG::NodeRefPtr planeNode = createPlane(texObjChunk);
184 OSG::AlgorithmComputeElementRefPtr algoCompElement = OSG::AlgorithmComputeElement::create();
185 OSG::NodeRefPtr computeNode = OSG::makeNodeFor(algoCompElement);
186 computeNode->addChild(planeNode);
188 OSG::ComputeShaderAlgorithmRefPtr compShaderAlgo = OSG::ComputeShaderAlgorithm::create();
189 algoCompElement->setAlgorithm(compShaderAlgo);
191 OSG::TextureImageChunkRefPtr texImgChunk = OSG::TextureImageChunk::create();
192 texImgChunk->setTexture(texObjChunk);
193 texImgChunk->setAccess(GL_WRITE_ONLY);
194 texImgChunk->setFormat(GL_RGBA32F);
196 OSG::ComputeShaderChunkRefPtr compShaderChunk = OSG::ComputeShaderChunk::create();
197 compShaderChunk->addUniformVariable("destTex", 0);
198 compShaderChunk->addUniformVariable("roll", 0.f);
199 compShaderChunk->setComputeProgram(get_cp_program());
201 compShaderAlgo->setComputeShader(compShaderChunk);
202 compShaderAlgo->pushToTextureImages(texImgChunk);
203 compShaderAlgo->setDispatchConfig(OSG::Vec3i(32, 32, 1));
205 OSG::NodeRefPtr scene = OSG::makeCoredNode<OSG::Group>();
206 scene->addChild(computeNode);
208 OSG::TimeSensorRefPtr sceneTimer = OSG::TimeSensor::create();
209 sceneTimer->setLoop(true);
210 sceneTimer->setCycleInterval(10);
212 OSG::VRMLScalarInterpolatorRefPtr rollInter = OSG::VRMLScalarInterpolator::create();
213 rollInter->editMFKeyValue()->push_back(0.f);
214 rollInter->editMFKeyValue()->push_back(10.24f);
216 rollInter->editMFKey()->push_back(0.f);
217 rollInter->editMFKey()->push_back(1.f);
219 const OSG::ShaderVariableReal* varRealRoll = dynamic_cast<const OSG::ShaderVariableReal*>(compShaderChunk->getVariables()->getVariable("roll"));
221 addConnection(sceneTimer, "fraction", rollInter, "inValue");
222 addConnection(rollInter, "outValue", const_cast<OSG::ShaderVariableReal*>(varRealRoll), "value");
224 OSG::ContainerCollectionRefPtr containerCollection = OSG::ContainerCollection::create();
226 containerCollection->addContainer(rollInter);
227 containerCollection->addContainer(sceneTimer);
229 scene->addAttachment(containerCollection);
231 return OSG::NodeTransitPtr(scene);
235 // forward declaration so we can have the interesting stuff upfront
237 int setupGLUT(int *argc, char *argv[]);
238 void releaseGLUT();
239 void print_help();
242 // Initialize GLUT & OpenSG and set up the scene
244 int main(int argc, char **argv)
246 OSG::preloadSharedObject("OSGImageFileIO");
248 // OSG init
249 OSG::osgInit(argc,argv);
251 // GLUT init
252 int winid = setupGLUT(&argc, argv);
254 print_help();
256 // open a new scope, because the pointers below should go out of scope
257 // before entering glutMainLoop.
258 // Otherwise OpenSG will complain about objects being alive after shutdown.
260 // the connection between GLUT and OpenSG
261 OSG::GLUTWindowRefPtr gwin = OSG::GLUTWindow::create();
262 gwin->setGlutId(winid);
263 gwin->init();
265 // create the SimpleSceneManager helper
266 mgr = OSG::SimpleSceneManager::create();
267 mgr->setWindow(gwin);
269 // The scene
270 OSG::NodeRefPtr scene = createScene();
272 mgr->setRoot(scene);
274 OSG::commitChanges();
276 // show the whole scene
277 mgr->showAll();
280 // GLUT main loop
281 glutMainLoop();
283 return 0;
287 // GLUT callback functions
291 // redraw the window
293 void display(void)
295 OSG::FrameHandler::the()->frame();
297 OSG::commitChanges();
299 mgr->redraw();
302 // react to size changes
304 void reshape(int w, int h)
306 mgr->resize(w, h);
307 glutPostRedisplay();
311 // react to mouse button presses
313 void mouse(int button, int state, int x, int y)
315 if (state)
316 mgr->mouseButtonRelease(button, x, y);
317 else
318 mgr->mouseButtonPress(button, x, y);
320 glutPostRedisplay();
324 // react to mouse motions with pressed buttons
326 void motion(int x, int y)
328 mgr->mouseMove(x, y);
329 glutPostRedisplay();
333 // react to keys
335 void keyboard(unsigned char k, int x, int y)
337 switch(k)
339 case 27: // ESC
341 // clean up global variables
342 mgr = NULL;
344 releaseGLUT();
346 OSG::osgExit();
347 exit(0);
349 break;
354 // setup the GLUT library which handles the windows for us
356 int setupGLUT(int *argc, char *argv[])
358 glutInit(argc, argv);
359 glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE);
360 glutInitWindowSize(1000, 800);
362 int winid = glutCreateWindow("OpenSG");
364 glutReshapeFunc(reshape);
365 glutDisplayFunc(display);
366 glutMouseFunc(mouse);
367 glutMotionFunc(motion);
368 glutKeyboardFunc(keyboard);
370 // call the redraw function whenever there's nothing else to do
371 glutIdleFunc(display);
373 return winid;
376 void releaseGLUT()
378 glutReshapeFunc(NULL);
379 glutDisplayFunc(NULL);
380 glutMouseFunc(NULL);
381 glutMotionFunc(NULL);
382 glutKeyboardFunc(NULL);
383 glutIdleFunc(NULL);
386 void print_help()
388 std::cout << "Esc : quit example" << std::endl;
392 std::string get_cp_program()
394 using namespace std;
396 stringstream ost;
398 ost << "#version 440 compatibility"
399 << endl << ""
400 << endl << "uniform float roll;"
401 << endl << "uniform writeonly image2D destTex;"
402 << endl << ""
403 << endl << "layout (local_size_x = 16, local_size_y = 16) in;"
404 << endl << ""
405 << endl << "void main()"
406 << endl << "{"
407 << endl << " ivec2 storePos = ivec2( gl_GlobalInvocationID.xy );"
408 << endl << " float localCoef = length( vec2( ivec2(gl_LocalInvocationID.xy) - 8 ) / 8.0 );"
409 << endl << " float globalCoef = sin( float(gl_WorkGroupID.x + gl_WorkGroupID.y) * 0.1 + roll ) * 0.5;"
410 << endl << ""
411 << endl << " imageStore(destTex, storePos, vec4(1.0 - globalCoef * localCoef, 0.0, 0.0, 0.0));"
412 << endl << "}"
413 << endl << ""
414 << endl;
416 return ost.str();