1 // OpenSG Example: ComputeShader2
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.
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
18 #include <OSGConfig.h>
19 #include <OSGSimpleGeometry.h>
20 #include <OSGGLUTWindow.h>
21 #include <OSGSimpleSceneManager.h>
22 #include <OSGBaseFunctions.h>
23 #include <OSGTransform.h>
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>
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>
46 #include <OSGTimeSensor.h>
47 #include <OSGTypedGeoIntegralProperty.h>
48 #include <OSGTypedGeoVectorProperty.h>
49 #include <OSGVRMLScalarInterpolator.h>
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>
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>
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
[]);
256 // Initialize GLUT & OpenSG and set up the scene
258 int main(int argc
, char **argv
)
260 OSG::preloadSharedObject("OSGImageFileIO");
263 OSG::osgInit(argc
,argv
);
266 int winid
= setupGLUT(&argc
, argv
);
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
);
279 // create the SimpleSceneManager helper
280 mgr
= OSG::SimpleSceneManager::create();
281 mgr
->setWindow(gwin
);
284 OSG::NodeRefPtr scene
= createScene();
288 OSG::commitChanges();
290 // show the whole scene
301 // GLUT callback functions
309 OSG::FrameHandler::the()->frame();
311 OSG::commitChanges();
316 // react to size changes
318 void reshape(int w
, int h
)
325 // react to mouse button presses
327 void mouse(int button
, int state
, int x
, int y
)
330 mgr
->mouseButtonRelease(button
, x
, y
);
332 mgr
->mouseButtonPress(button
, x
, y
);
338 // react to mouse motions with pressed buttons
340 void motion(int x
, int y
)
342 mgr
->mouseMove(x
, y
);
349 void keyboard(unsigned char k
, int x
, int y
)
355 // clean up global variables
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
);
392 glutReshapeFunc(NULL
);
393 glutDisplayFunc(NULL
);
395 glutMotionFunc(NULL
);
396 glutKeyboardFunc(NULL
);
402 std::cout
<< "Esc : quit example" << std::endl
;
406 std::string
get_cp_program()
412 ost
<< "#version 440 compatibility"
414 << endl
<< "uniform float roll;"
415 << endl
<< "uniform writeonly image2D destTex;"
417 << endl
<< "layout (local_size_x = 16, local_size_y = 16) in;"
419 << endl
<< "void main()"
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;"
425 << endl
<< " imageStore(destTex, storePos, vec4(1.0 - globalCoef * localCoef, 0.0, 0.0, 0.0));"