1 // OpenSG Example: ComputeShader1
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.
8 #ifdef OSG_BUILD_ACTIVE
11 #include <OSGConfig.h>
12 #include <OSGSimpleGeometry.h>
13 #include <OSGGLUTWindow.h>
14 #include <OSGSimpleSceneManager.h>
15 #include <OSGBaseFunctions.h>
16 #include <OSGTransform.h>
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>
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>
38 #include <OSGTimeSensor.h>
39 #include <OSGTypedGeoIntegralProperty.h>
40 #include <OSGTypedGeoVectorProperty.h>
41 #include <OSGVRMLScalarInterpolator.h>
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>
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>
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
[]);
242 // Initialize GLUT & OpenSG and set up the scene
244 int main(int argc
, char **argv
)
246 OSG::preloadSharedObject("OSGImageFileIO");
249 OSG::osgInit(argc
,argv
);
252 int winid
= setupGLUT(&argc
, argv
);
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
);
265 // create the SimpleSceneManager helper
266 mgr
= OSG::SimpleSceneManager::create();
267 mgr
->setWindow(gwin
);
270 OSG::NodeRefPtr scene
= createScene();
274 OSG::commitChanges();
276 // show the whole scene
287 // GLUT callback functions
295 OSG::FrameHandler::the()->frame();
297 OSG::commitChanges();
302 // react to size changes
304 void reshape(int w
, int h
)
311 // react to mouse button presses
313 void mouse(int button
, int state
, int x
, int y
)
316 mgr
->mouseButtonRelease(button
, x
, y
);
318 mgr
->mouseButtonPress(button
, x
, y
);
324 // react to mouse motions with pressed buttons
326 void motion(int x
, int y
)
328 mgr
->mouseMove(x
, y
);
335 void keyboard(unsigned char k
, int x
, int y
)
341 // clean up global variables
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
);
378 glutReshapeFunc(NULL
);
379 glutDisplayFunc(NULL
);
381 glutMotionFunc(NULL
);
382 glutKeyboardFunc(NULL
);
388 std::cout
<< "Esc : quit example" << std::endl
;
392 std::string
get_cp_program()
398 ost
<< "#version 440 compatibility"
400 << endl
<< "uniform float roll;"
401 << endl
<< "uniform writeonly image2D destTex;"
403 << endl
<< "layout (local_size_x = 16, local_size_y = 16) in;"
405 << endl
<< "void main()"
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;"
411 << endl
<< " imageStore(destTex, storePos, vec4(1.0 - globalCoef * localCoef, 0.0, 0.0, 0.0));"