fixed: auto_ptr -> unique_ptr
[opensg.git] / Examples / Simple / shaderstoragebufferobject_test.cpp
blob15b757767359ae784656a36ef71862cd2bc4f43c
1 // OpenSG Test Example: ShaderStorageBufferObject_Test
2 //
3 // This example allows to research the capabilities of the shader
4 // storage buffer object extension on your graphics platform.
5 //
6 // This example is similar to the ShaderStorageBufferObject_Test_1
7 // example. This one uses a non array block layout, whereas the
8 // test_1 example uses an even more complex setup with an array
9 // block layout.
11 // The example does use the ShaderStorageObjChunk which allows the
12 // host application to provide the shader storage block member values
13 // directly to the chunk. The layout of the shader storage block is determined
14 // by the shader code. Any of the layout values of the specification (shared,
15 // packed, std140, std430) are allowed.
17 // Outcome on running this example:
18 // 1. animated green cylinder and torus
19 // => your platform provides all GLSL capabilities used in this
20 // example. Congratulations :-)
22 // 2. animated red cylinder and torus
23 // => the shader is actively working but some detail is not
24 // working properly. E.g.:
25 // - On ATI/AMD the usage of bvec2 fails at the time of writing
26 // the example on the authors Radeon 5700 series
27 // platform, iff the 'std140' layout is used.
28 // - On ATI/AMD the usage of double and dvec2 fails at the time
29 // writing the example on the authors Radeon 5700 series
30 // platform.
32 // 3. animated gold looking cylinder and torus
33 // => the shader is not working at all. Something is miserabely
34 // wrong on your platform.
36 // The example uses the following shader storage block named 'ExampleBlock'
37 // which is declared in the shader code below.
39 // struct Test
40 // {
41 // float t;
42 // ivec3 v[3];
43 // int w;
44 // };
46 // layout(shared) buffer ExampleBlock {
47 // float a;
48 // vec2 b;
49 // vec3 c;
50 // struct {
51 // int d;
52 // bvec2 e;
53 // } f;
54 // float g;
55 // float h[2];
56 // mat2x3 i;
57 // struct {
58 // uvec3 j;
59 // vec2 k;
60 // float l[2];
61 // vec2 m;
62 // mat3 n[2];
63 // } o[2];
64 // double p;
65 // bool q;
66 // struct {
67 // dvec2 r;
68 // int s;
69 // Test x[4]; // structs can not explicitely be nested but implicit nesting is fine
70 // } y;
71 // } example;
73 // For this example the values must be provided for the following data slots:
75 // "ExampleBlock.a"
76 // "ExampleBlock.b"
77 // "ExampleBlock.c"
78 // "ExampleBlock.f.d"
79 // "ExampleBlock.f.e"
80 // "ExampleBlock.g"
81 // "ExampleBlock.h[0]"
82 // "ExampleBlock.h[1]"
83 // "ExampleBlock.i"
84 // "ExampleBlock.o[0].j"
85 // "ExampleBlock.o[0].k"
86 // "ExampleBlock.o[0].l[0]"
87 // "ExampleBlock.o[0].l[1]"
88 // "ExampleBlock.o[0].m"
89 // "ExampleBlock.o[0].n[0]"
90 // "ExampleBlock.o[0].n[1]"
91 // "ExampleBlock.o[1].j"
92 // "ExampleBlock.o[1].k"
93 // "ExampleBlock.o[1].l[0]"
94 // "ExampleBlock.o[1].l[1]"
95 // "ExampleBlock.o[1].m"
96 // "ExampleBlock.o[1].n[0]"
97 // "ExampleBlock.o[1].n[1]"
98 // "ExampleBlock.p"
99 // "ExampleBlock.q"
100 // "ExampleBlock.y.r"
101 // "ExampleBlock.y.s"
102 // "ExampleBlock.y.x[0].t"
103 // "ExampleBlock.y.x[0].v[0]"
104 // "ExampleBlock.y.x[0].v[1]"
105 // "ExampleBlock.y.x[0].v[2]"
106 // "ExampleBlock.y.x[0].w"
107 // "ExampleBlock.y.x[1].t"
108 // "ExampleBlock.y.x[1].v[0]"
109 // "ExampleBlock.y.x[1].v[1]"
110 // "ExampleBlock.y.x[1].v[2]"
111 // "ExampleBlock.y.x[1].w"
112 // "ExampleBlock.y.x[2].t"
113 // "ExampleBlock.y.x[2].v[0]"
114 // "ExampleBlock.y.x[2].v[1]"
115 // "ExampleBlock.y.x[2].v[2]"
116 // "ExampleBlock.y.x[2].w"
117 // "ExampleBlock.y.x[3].t"
118 // "ExampleBlock.y.x[3].v[0]"
119 // "ExampleBlock.y.x[3].v[1]"
120 // "ExampleBlock.y.x[3].v[2]"
121 // "ExampleBlock.y.x[3].w"
124 #ifdef OSG_BUILD_ACTIVE
125 // Headers
126 #include <OSGGLUT.h>
127 #include <OSGConfig.h>
128 #include <OSGSimpleGeometry.h>
129 #include <OSGGLUTWindow.h>
130 #include <OSGSimpleSceneManager.h>
131 #include <OSGBaseFunctions.h>
132 #include <OSGTransform.h>
133 #include <OSGGroup.h>
135 // new headers:
136 #include <OSGGLEXT.h>
137 #include <OSGShaderProgramChunk.h>
138 #include <OSGShaderProgram.h>
139 #include <OSGShaderVariableOSG.h>
140 #include <OSGChunkMaterial.h>
141 #include <OSGMaterialGroup.h>
142 #include <OSGMaterialChunkOverrideGroup.h>
143 #include <OSGShaderStorageBufferObjChunk.h>
144 #include <OSGPolygonChunk.h>
145 #include <OSGDepthChunk.h>
146 #include <OSGShaderProgramVariableChunk.h>
148 #else
149 // Headers
150 #include <OpenSG/OSGGLUT.h>
151 #include <OpenSG/OSGConfig.h>
152 #include <OpenSG/OSGSimpleGeometry.h>
153 #include <OpenSG/OSGGLUTWindow.h>
154 #include <OpenSG/OSGSimpleSceneManager.h>
155 #include <OpenSG/OSGBaseFunctions.h>
156 #include <OpenSG/OSGTransform.h>
157 #include <OpenSG/OSGGroup.h>
159 // new headers:
160 #include <OpenSG/OSGGLEXT.h>
161 #include <OpenSG/OSGShaderProgramChunk.h>
162 #include <OpenSG/OSGShaderProgram.h>
163 #include <OpenSG/OSGShaderVariableOSG.h>
164 #include <OpenSG/OSGChunkMaterial.h>
165 #include <OpenSG/OSGMaterialGroup.h>
166 #include <OpenSG/OSGMaterialChunkOverrideGroup.h>
167 #include <OpenSG/OSGShaderStorageBufferObjChunk.h>
168 #include <OpenSG/OSGPolygonChunk.h>
169 #include <OpenSG/OSGDepthChunk.h>
170 #include <OpenSG/OSGShaderProgramVariableChunk.h>
171 #endif
173 #define HAS_FP64_EXTENSION
176 // The SimpleSceneManager to manage simple applications
178 OSG::SimpleSceneManagerRefPtr mgr;
181 // Create a OpenSG ShaderStorageBufferObjChunk object which does
182 // perform the shader storage buffer object abstraction.
183 // For each block member entry (declared in the shader) a
184 // corresponding addXXX call is to be performed on the
185 // ssbo chunk. The cardinality for arrays must be provided
186 // to the function calls (defaults to 1).
187 // The matrix functions are defined in column-major order
188 // matching the default definition of GLSL. I.e. a addMat2x3(2)
189 // call would request space and layout for an array of two
190 // matrices with two columns and three rows.
192 OSG::ShaderStorageBufferObjChunkTransitPtr create_example_block_state()
194 OSG::ShaderStorageBufferObjChunkRefPtr ssbo = OSG::ShaderStorageBufferObjChunk::create();
196 ssbo->setBlockName("ExampleBlock");
197 ssbo->setUsage(GL_STREAM_DRAW);
199 ssbo->addFloat ("ExampleBlock.a");
200 ssbo->addVec2 ("ExampleBlock.b");
201 ssbo->addVec3 ("ExampleBlock.c");
202 ssbo->addInt ("ExampleBlock.f.d");
203 ssbo->addBVec2 ("ExampleBlock.f.e");
204 ssbo->addFloat ("ExampleBlock.g");
205 ssbo->addFloat ("ExampleBlock.h", 2);
206 ssbo->addMat2x3 ("ExampleBlock.i"); // 2 columns and 3 rows
207 ssbo->addUVec3 ("ExampleBlock.o[0].j");
208 ssbo->addVec2 ("ExampleBlock.o[0].k");
209 ssbo->addFloat ("ExampleBlock.o[0].l", 2);
210 ssbo->addVec2 ("ExampleBlock.o[0].m");
211 ssbo->addMat3 ("ExampleBlock.o[0].n", 2);
213 ssbo->addUVec3 ("ExampleBlock.o[1].j");
214 ssbo->addVec2 ("ExampleBlock.o[1].k");
215 ssbo->addFloat ("ExampleBlock.o[1].l", 2);
216 ssbo->addVec2 ("ExampleBlock.o[1].m");
217 ssbo->addMat3 ("ExampleBlock.o[1].n", 2);
219 #ifdef HAS_FP64_EXTENSION
220 ssbo->addDouble ("ExampleBlock.p");
221 #endif
222 ssbo->addBool ("ExampleBlock.q");
224 #ifdef HAS_FP64_EXTENSION
225 ssbo->addDVec2 ("ExampleBlock.y.r");
226 #endif
227 ssbo->addInt ("ExampleBlock.y.s");
229 ssbo->addFloat ("ExampleBlock.y.x[0].t");
230 ssbo->addIVec3 ("ExampleBlock.y.x[0].v", 3);
231 ssbo->addInt ("ExampleBlock.y.x[0].w");
233 ssbo->addFloat ("ExampleBlock.y.x[1].t");
234 ssbo->addIVec3 ("ExampleBlock.y.x[1].v", 3);
235 ssbo->addInt ("ExampleBlock.y.x[1].w");
237 ssbo->addFloat ("ExampleBlock.y.x[2].t");
238 ssbo->addIVec3 ("ExampleBlock.y.x[2].v", 3);
239 ssbo->addInt ("ExampleBlock.y.x[2].w");
241 ssbo->addFloat ("ExampleBlock.y.x[3].t");
242 ssbo->addIVec3 ("ExampleBlock.y.x[3].v", 3);
243 ssbo->addInt ("ExampleBlock.y.x[3].w");
245 return OSG::ShaderStorageBufferObjChunkTransitPtr(ssbo);
249 // Fill the ssbo chunk with values.
251 void update_example_block_state(OSG::ShaderStorageBufferObjChunk* ssbo)
253 ssbo->setFloat ("ExampleBlock.a", 23.7f);
254 ssbo->setVec2 ("ExampleBlock.b", OSG::Vec2f(1.4f, 8.6f));
255 ssbo->setVec3 ("ExampleBlock.c", OSG::Vec3f(0.1f, 0.2f, 0.3f));
257 ssbo->setInt ("ExampleBlock.f.d", 14);
258 ssbo->setBVec2 ("ExampleBlock.f.e", OSG::Vec2b(true, false));
259 ssbo->setFloat ("ExampleBlock.g", 15.3f);
260 ssbo->setFloat ("ExampleBlock.h", 17.6f, 0);
261 ssbo->setFloat ("ExampleBlock.h", 19.3f, 1);
263 // Matrix mxn (m rows and n columns):
264 // ----------------------------------
265 // test_mat = a11 a12 a13 a14
266 // a21 a22 a23 a24
267 // a31 a32 a33 a34
268 // a41 a42 a43 a44
269 // OpenSG takes rows...
270 OSG::Matrix4f mat1( 11,12,13,14, // row 1
271 21,22,23,24, // row 2
272 31,32,33,34, // row 3
273 41,42,43,44 ); // row 4
275 // ... and provides elements in column-major order
276 // OSG::Real32* storage = mat1.getValues();
277 OSG::Vec4f column1 = mat1[1];
278 OSG::Vec4f column2 = mat1[2];
279 OSG::Vec4f column3 = mat1[3];
280 OSG::Vec4f column4 = mat1[4];
282 // GLSL uses column-major layout, i.e. mat2x3 is a matrix with 2 colums and 3 rows
284 // mat2x3 = a11 a12
285 // a21 a22
286 // a31 a32
288 ssbo->setMat2x3("ExampleBlock.i", mat1);
290 ssbo->setUVec3 ("ExampleBlock.o[0].j", OSG::Vec3u(1, 2, 3));
291 ssbo->setVec2 ("ExampleBlock.o[0].k", OSG::Vec2f(1.1f, 2.2f));
292 ssbo->setFloat ("ExampleBlock.o[0].l", 11.1f, 0);
293 ssbo->setFloat ("ExampleBlock.o[0].l", 22.2f, 1);
294 ssbo->setVec2 ("ExampleBlock.o[0].m", OSG::Vec2f(22.2f, 33.3f));
296 OSG::Matrix4f mat2( 1.1f, 1.2f, 1.3f, 1.4f, // row 1
297 2.1f, 2.2f, 2.3f, 2.4f, // row 2
298 3.1f, 3.2f, 3.3f, 3.4f, // row 3
299 4.1f, 4.2f, 4.3f, 4.4f ); // row 4
301 ssbo->setMat3 ("ExampleBlock.o[0].n", mat2, 0);
303 OSG::Matrix4f mat3( 10.1f, 10.2f, 10.3f, 10.4f, // row 1
304 20.1f, 20.2f, 20.3f, 20.4f, // row 2
305 30.1f, 30.2f, 30.3f, 30.4f, // row 3
306 40.1f, 40.2f, 40.3f, 40.4f ); // row 4
308 ssbo->setMat3 ("ExampleBlock.o[0].n", mat3, 1);
310 ssbo->setUVec3 ("ExampleBlock.o[1].j", OSG::Vec3u(7, 8, 9));
311 ssbo->setVec2 ("ExampleBlock.o[1].k", OSG::Vec2f(7.7f, 8.8f));
312 ssbo->setFloat ("ExampleBlock.o[1].l", 77.7f, 0);
313 ssbo->setFloat ("ExampleBlock.o[1].l", 88.8f, 1);
314 ssbo->setVec2 ("ExampleBlock.o[1].m", OSG::Vec2f(88.8f, 99.9f));
316 OSG::Matrix4f mat4( 100.1f, 100.2f, 100.3f, 100.4f, // row 1
317 200.1f, 200.2f, 200.3f, 200.4f, // row 2
318 300.1f, 300.2f, 300.3f, 300.4f, // row 3
319 400.1f, 400.2f, 400.3f, 400.4f ); // row 4
321 ssbo->setMat3 ("ExampleBlock.o[1].n", mat4, 0);
323 OSG::Matrix4f mat5( 1000.1f, 1000.2f, 1000.3f, 1000.4f, // row 1
324 2000.1f, 2000.2f, 2000.3f, 2000.4f, // row 2
325 3000.1f, 3000.2f, 3000.3f, 3000.4f, // row 3
326 4000.1f, 4000.2f, 4000.3f, 4000.4f ); // row 4
328 ssbo->setMat3 ("ExampleBlock.o[1].n", mat5, 1);
330 #ifdef HAS_FP64_EXTENSION
331 ssbo->setDouble("ExampleBlock.p", 17856.23456);
332 #endif
333 ssbo->setBool ("ExampleBlock.q", true);
335 #ifdef HAS_FP64_EXTENSION
336 ssbo->setDVec2 ("ExampleBlock.y.r", OSG::Vec2d(9567.123, 2345.63456));
337 #endif
338 ssbo->setInt ("ExampleBlock.y.s", 123);
340 ssbo->setFloat ("ExampleBlock.y.x[0].t", 1.001f);
341 ssbo->setIVec3 ("ExampleBlock.y.x[0].v", OSG::Vec3i(1,0,1), 0);
342 ssbo->setIVec3 ("ExampleBlock.y.x[0].v", OSG::Vec3i(2,0,2), 1);
343 ssbo->setIVec3 ("ExampleBlock.y.x[0].v", OSG::Vec3i(3,0,3), 2);
344 ssbo->setInt ("ExampleBlock.y.x[0].w", 1);
346 ssbo->setFloat ("ExampleBlock.y.x[1].t", 2.002f);
347 ssbo->setIVec3 ("ExampleBlock.y.x[1].v", OSG::Vec3i(4,0,4), 0);
348 ssbo->setIVec3 ("ExampleBlock.y.x[1].v", OSG::Vec3i(5,0,5), 1);
349 ssbo->setIVec3 ("ExampleBlock.y.x[1].v", OSG::Vec3i(6,0,6), 2);
350 ssbo->setInt ("ExampleBlock.y.x[1].w", 2);
352 ssbo->setFloat ("ExampleBlock.y.x[2].t", 3.003f);
353 ssbo->setIVec3 ("ExampleBlock.y.x[2].v", OSG::Vec3i(7,0,7), 0);
354 ssbo->setIVec3 ("ExampleBlock.y.x[2].v", OSG::Vec3i(8,0,8), 1);
355 ssbo->setIVec3 ("ExampleBlock.y.x[2].v", OSG::Vec3i(9,0,9), 2);
356 ssbo->setInt ("ExampleBlock.y.x[2].w", 3);
358 ssbo->setFloat ("ExampleBlock.y.x[3].t", 4.004f);
359 ssbo->setIVec3 ("ExampleBlock.y.x[3].v", OSG::Vec3i(1,4,6), 0);
360 ssbo->setIVec3 ("ExampleBlock.y.x[3].v", OSG::Vec3i(2,5,7), 1);
361 ssbo->setIVec3 ("ExampleBlock.y.x[3].v", OSG::Vec3i(3,6,8), 2);
362 ssbo->setInt ("ExampleBlock.y.x[3].w", 4);
366 // vertex shader program.
368 std::string get_vp_program();
371 // fragment shader program for bump mapping in surface local coordinates
373 std::string get_fp_program();
376 // a separate transformation for every object
378 OSG::TransformRefPtr cyltrans, tortrans;
381 // forward declaration so we can have the interesting stuff upfront
383 int setupGLUT(int *argc, char *argv[]);
386 // redraw the window
388 void display(void)
390 // create the matrix
391 OSG::Matrix m;
392 OSG::Real32 t = glutGet(GLUT_ELAPSED_TIME );
394 // set the transforms' matrices
395 m.setTransform(OSG::Vec3f(0, 0, OSG::osgSin(t / 1000.f) * 1.5),
396 OSG::Quaternion( OSG::Vec3f (1, 0, 0), t / 500.f));
398 cyltrans->setMatrix(m);
400 m.setTransform(OSG::Vec3f(OSG::osgSin(t / 1000.f), 0, 0),
401 OSG::Quaternion( OSG::Vec3f (0, 0, 1), t / 1000.f));
403 tortrans->setMatrix(m);
405 OSG::commitChanges();
407 mgr->redraw();
411 // Initialize GLUT & OpenSG and set up the scene
413 int main(int argc, char **argv)
415 // OSG init
416 OSG::osgInit(argc,argv);
418 // GLUT init
419 int winid = setupGLUT(&argc, argv);
421 // open a new scope, because the pointers below should go out of scope
422 // before entering glutMainLoop.
423 // Otherwise OpenSG will complain about objects being alive after shutdown.
425 // the connection between GLUT and OpenSG
426 OSG::GLUTWindowRefPtr gwin = OSG::GLUTWindow::create();
427 gwin->setGlutId(winid);
428 gwin->init();
430 // create the SimpleSceneManager helper
431 mgr = OSG::SimpleSceneManager::create();
432 mgr->setWindow(gwin);
434 // create a pretty simple graph: a Group with two Transforms as children,
435 // each of which carries a single Geometry.
437 // The scene
439 OSG::NodeRefPtr scene = OSG::Node::create();
441 // The cylinder and its transformation
442 OSG::NodeRefPtr cyl = OSG::Node::create();
443 OSG::GeometryRefPtr cylgeo = OSG::makeCylinderGeo( 1.4f, .3f, 24,
444 true, true, true );
446 cyl->setCore(cylgeo);
448 cyltrans = OSG::Transform::create();
450 OSG::NodeRefPtr cyltransnode = OSG::Node::create();
451 cyltransnode->setCore (cyltrans);
452 cyltransnode->addChild(cyl );
454 // add it to the scene
455 scene->addChild(cyltransnode);
457 // The torus and its transformation
458 OSG::NodeRefPtr torus = OSG::Node::create();
459 OSG::GeometryRefPtr torusgeo = OSG::makeTorusGeo( .2f, 1, 24, 36 );
461 torus->setCore(torusgeo);
463 tortrans = OSG::Transform::create();
465 OSG::NodeRefPtr tortransnode = OSG::Node::create();
466 tortransnode->setCore (tortrans);
467 tortransnode->addChild(torus );
469 // add it to the scene
470 scene->addChild(tortransnode);
473 // create the shader program
475 OSG::ShaderProgramChunkRefPtr prog_chunk = OSG::ShaderProgramChunk::create();
476 OSG::ShaderProgramRefPtr vertShader = OSG::ShaderProgram::createVertexShader();
477 OSG::ShaderProgramRefPtr fragShader = OSG::ShaderProgram::createFragmentShader();
479 vertShader->setProgram(get_vp_program());
480 fragShader->setProgram(get_fp_program());
483 // binding the shader storage block to a buffer binding point can be performed
484 // either by calling the shaders's addShaderStorageBlock method or by
485 // adding a 'buffer block' variable to a ShaderProgramVariableChunk.
486 // In the following we use both variants for illustration.
488 fragShader->addShaderStorageBlock("ExampleBlock", 1); // block binding point
490 prog_chunk->addShader(vertShader);
491 prog_chunk->addShader(fragShader);
494 // create shader storage buffer object for block 'ExampleBlock'
496 OSG::ShaderStorageBufferObjChunkRefPtr ssbo_example_block = create_example_block_state();
498 update_example_block_state(ssbo_example_block);
500 OSG::PolygonChunkRefPtr polygon_chunk = OSG::PolygonChunk::create();
501 polygon_chunk->setFrontMode(GL_FILL);
502 polygon_chunk->setBackMode(GL_FILL);
503 polygon_chunk->setCullFace(GL_NONE);
505 OSG::DepthChunkRefPtr depth_chunk = OSG::DepthChunk::create();
506 depth_chunk->setEnable(true);
508 OSG::ChunkMaterialRefPtr prog_state = OSG::ChunkMaterial::create();
509 prog_state->addChunk(ssbo_example_block, 1); // buffer binding point 1
510 prog_state->addChunk(prog_chunk);
511 prog_state->addChunk(polygon_chunk);
512 prog_state->addChunk(depth_chunk);
514 OSG::MaterialChunkOverrideGroupRefPtr mgrp = OSG::MaterialChunkOverrideGroup::create();
515 mgrp->setMaterial(prog_state);
516 scene->setCore(mgrp);
518 OSG::commitChanges();
520 mgr->setRoot(scene);
522 // show the whole scene
523 mgr->showAll();
526 // GLUT main loop
527 glutMainLoop();
529 return 0;
533 // GLUT callback functions
537 // react to size changes
539 void reshape(int w, int h)
541 mgr->resize(w, h);
542 glutPostRedisplay();
546 // react to mouse button presses
548 void mouse(int button, int state, int x, int y)
550 if (state)
551 mgr->mouseButtonRelease(button, x, y);
552 else
553 mgr->mouseButtonPress(button, x, y);
555 glutPostRedisplay();
559 // react to mouse motions with pressed buttons
561 void motion(int x, int y)
563 mgr->mouseMove(x, y);
564 glutPostRedisplay();
568 // react to keys
570 void keyboard(unsigned char k, int x, int y)
572 switch(k)
574 case 27:
576 // clean up global variables
577 cyltrans = NULL;
578 tortrans = NULL;
579 mgr = NULL;
581 OSG::osgExit();
582 exit(0);
584 break;
586 case 's':
588 mgr->setStatistics(!mgr->getStatistics());
590 break;
595 // setup the GLUT library which handles the windows for us
597 int setupGLUT(int *argc, char *argv[])
599 glutInit(argc, argv);
600 glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE);
602 int winid = glutCreateWindow("OpenSG");
604 glutReshapeFunc(reshape);
605 glutDisplayFunc(display);
606 glutMouseFunc(mouse);
607 glutMotionFunc(motion);
608 glutKeyboardFunc(keyboard);
610 // call the redraw function whenever there's nothing else to do
611 glutIdleFunc(display);
613 return winid;
617 // vertex shader program.
619 std::string get_vp_program()
621 std::string vp_program =
622 "\n"
623 "#version 330 compatibility\n"
624 "\n"
625 "#extension GL_ARB_separate_shader_objects: enable\n"
626 "#extension GL_ARB_uniform_buffer_object: enable\n"
627 "\n"
628 "void main()\n"
629 "{\n"
630 " gl_Position = ftransform();\n"
631 "}\n"
632 "\n"
635 return vp_program;
639 // fragment shader program for bump mapping in surface local coordinates
641 std::string get_fp_program()
643 std::string fp_program =
644 "\n"
645 "#version 440 compatibility\n"
646 "\n"
647 "#extension GL_ARB_separate_shader_objects: enable\n"
648 "#extension GL_ARB_shader_storage_buffer_object: enable\n"
649 "\n"
650 #ifdef HAS_FP64_EXTENSION
651 "#extension GL_ARB_gpu_shader_fp64: enable\n"
652 #endif
653 "\n"
654 "struct Test\n"
655 "{\n"
656 " float t;\n"
657 " ivec3 v[3];\n"
658 " int w;\n"
659 "};\n"
660 "\n"
661 "layout (shared) buffer ExampleBlock\n"
662 "{\n"
663 " float a;\n"
664 " vec2 b;\n"
665 " vec3 c;\n"
666 " struct {\n"
667 " int d;\n"
668 " bvec2 e;\n"
669 " } f;\n"
670 " float g;\n"
671 " float h[2];\n"
672 " mat2x3 i;\n"
673 " struct {\n"
674 " uvec3 j;\n"
675 " vec2 k;\n"
676 " float l[2];\n"
677 " vec2 m;\n"
678 " mat3 n[2];\n"
679 " } o[2];\n"
680 #ifdef HAS_FP64_EXTENSION
681 " double p;\n"
682 #endif
683 " bool q;\n"
684 " struct {\n"
685 #ifdef HAS_FP64_EXTENSION
686 " dvec2 r;\n"
687 #endif
688 " int s;\n"
689 " Test x[4]; // structs can not explicitely be nested but implicit nesting is fine\n"
690 " } y;\n"
691 " } example;\n"
692 "\n"
693 "layout(location = 0) out vec4 vFragColor;\n"
694 "\n"
695 "void main()\n"
696 "{\n"
697 "\n"
698 " vec4 error = vec4(1.0, 0.0, 0.0, 1.0);\n"
699 " vec4 color = vec4(0.0, 1.0, 0.0, 1.0);\n"
700 "\n"
701 "\n"
702 " float a = example.a;\n"
703 " vec2 b = example.b;\n"
704 " vec3 c = example.c;\n"
705 " int d = example.f.d;\n"
706 " bvec2 e = example.f.e;\n"
707 " float g = example.g;\n"
708 " float h0 = example.h[0];\n"
709 " float h1 = example.h[1];\n"
710 " mat2x3 i = example.i;\n"
711 " uvec3 j0 = example.o[0].j;\n"
712 " vec2 k0 = example.o[0].k;\n"
713 " float l00 = example.o[0].l[0];\n"
714 " float l01 = example.o[0].l[1];\n"
715 " vec2 m0 = example.o[0].m;\n"
716 " mat3 n00 = example.o[0].n[0];\n"
717 " mat3 n01 = example.o[0].n[1];\n"
718 " uvec3 j1 = example.o[1].j;\n"
719 " vec2 k1 = example.o[1].k;\n"
720 " float l10 = example.o[1].l[0];\n"
721 " float l11 = example.o[1].l[1];\n"
722 " vec2 m1 = example.o[1].m;\n"
723 " mat3 n10 = example.o[1].n[0];\n"
724 " mat3 n11 = example.o[1].n[1];\n"
725 #ifdef HAS_FP64_EXTENSION
726 " double p = example.p;\n"
727 #endif
728 " bool q = example.q;\n"
729 #ifdef HAS_FP64_EXTENSION
730 " dvec2 r = example.y.r;\n"
731 #endif
732 " int s = example.y.s;\n"
733 " float t0 = example.y.x[0].t;\n"
734 " ivec3 v00 = example.y.x[0].v[0];\n"
735 " ivec3 v01 = example.y.x[0].v[1];\n"
736 " ivec3 v02 = example.y.x[0].v[2];\n"
737 " int w0 = example.y.x[0].w;\n"
738 " float t1 = example.y.x[1].t;\n"
739 " ivec3 v10 = example.y.x[1].v[0];\n"
740 " ivec3 v11 = example.y.x[1].v[1];\n"
741 " ivec3 v12 = example.y.x[1].v[2];\n"
742 " int w1 = example.y.x[1].w;\n"
743 " float t2 = example.y.x[2].t;\n"
744 " ivec3 v20 = example.y.x[2].v[0];\n"
745 " ivec3 v21 = example.y.x[2].v[1];\n"
746 " ivec3 v22 = example.y.x[2].v[2];\n"
747 " int w2 = example.y.x[2].w;\n"
748 " float t3 = example.y.x[3].t;\n"
749 " ivec3 v30 = example.y.x[3].v[0];\n"
750 " ivec3 v31 = example.y.x[3].v[1];\n"
751 " ivec3 v32 = example.y.x[3].v[2];\n"
752 " int w3 = example.y.x[3].w;\n"
753 "\n"
754 "\n"
755 " if (a != 23.7)\n"
756 " color = error;\n"
757 "\n"
758 " if (b != vec2(1.4, 8.6))\n"
759 " color = error;\n"
760 "\n"
761 " if (c != vec3(0.1, 0.2, 0.3))\n"
762 " color = error;\n"
763 "\n"
764 " if (d != 14)\n"
765 " color = error;\n"
766 "\n"
767 " if (e != bvec2(true, false))\n"
768 " color = error;\n"
769 "\n"
770 " if (g != 15.3)\n"
771 " color = error;\n"
772 "\n"
773 " if (h0 != 17.6)\n"
774 " color = error;\n"
775 "\n"
776 " if (h1 != 19.3)\n"
777 " color = error;\n"
778 "\n"
779 " if (i[0][0] != 11)\n"
780 " color = error;\n"
781 "\n"
782 " if (i[0][1] != 21)\n"
783 " color = error;\n"
784 "\n"
785 " if (i[0][2] != 31)\n"
786 " color = error;\n"
787 "\n"
788 " if (i[1][0] != 12)\n"
789 " color = error;\n"
790 "\n"
791 " if (i[1][1] != 22)\n"
792 " color = error;\n"
793 "\n"
794 " if (i[1][2] != 32)\n"
795 " color = error;\n"
796 "\n"
797 " if (j0 != uvec3(1, 2, 3))\n"
798 " color = error;\n"
799 "\n"
800 " if (k0 != vec2(1.1, 2.2))\n"
801 " color = error;\n"
802 "\n"
803 " if (l00 != 11.1)\n"
804 " color = error;\n"
805 "\n"
806 " if (l01 != 22.2)\n"
807 " color = error;\n"
808 "\n"
809 " if (m0 != vec2(22.2, 33.3))\n"
810 " color = error;\n"
811 "\n"
812 " if (n00[0][0] != 1.1)\n"
813 " color = error;\n"
814 "\n"
815 " if (n00[0][1] != 2.1)\n"
816 " color = error;\n"
817 "\n"
818 " if (n00[0][2] != 3.1)\n"
819 " color = error;\n"
820 "\n"
821 " if (n00[1][0] != 1.2)\n"
822 " color = error;\n"
823 "\n"
824 " if (n00[1][1] != 2.2)\n"
825 " color = error;\n"
826 "\n"
827 " if (n00[1][2] != 3.2)\n"
828 " color = error;\n"
829 "\n"
830 " if (n00[2][0] != 1.3)\n"
831 " color = error;\n"
832 "\n"
833 " if (n00[2][1] != 2.3)\n"
834 " color = error;\n"
835 "\n"
836 " if (n00[2][2] != 3.3)\n"
837 " color = error;\n"
838 "\n"
839 " if (n01[0][0] != 10.1)\n"
840 " color = error;\n"
841 "\n"
842 " if (n01[0][1] != 20.1)\n"
843 " color = error;\n"
844 "\n"
845 " if (n01[0][2] != 30.1)\n"
846 " color = error;\n"
847 "\n"
848 " if (n01[1][0] != 10.2)\n"
849 " color = error;\n"
850 "\n"
851 " if (n01[1][1] != 20.2)\n"
852 " color = error;\n"
853 "\n"
854 " if (n01[1][2] != 30.2)\n"
855 " color = error;\n"
856 "\n"
857 " if (n01[2][0] != 10.3)\n"
858 " color = error;\n"
859 "\n"
860 " if (n01[2][1] != 20.3)\n"
861 " color = error;\n"
862 "\n"
863 " if (n01[2][2] != 30.3)\n"
864 " color = error;\n"
865 "\n"
866 " if (j1 != uvec3(7, 8, 9))\n"
867 " color = error;\n"
868 "\n"
869 " if (k1 != vec2(7.7, 8.8))\n"
870 " color = error;\n"
871 "\n"
872 " if (l10 != 77.7)\n"
873 " color = error;\n"
874 "\n"
875 " if (l11 != 88.8)\n"
876 " color = error;\n"
877 "\n"
878 " if (m1 != vec2(88.8, 99.9))\n"
879 " color = error;\n"
880 "\n"
881 " if (n10[0][0] != 100.1)\n"
882 " color = error;\n"
883 "\n"
884 " if (n10[0][1] != 200.1)\n"
885 " color = error;\n"
886 "\n"
887 " if (n10[0][2] != 300.1)\n"
888 " color = error;\n"
889 "\n"
890 " if (n10[1][0] != 100.2)\n"
891 " color = error;\n"
892 "\n"
893 " if (n10[1][1] != 200.2)\n"
894 " color = error;\n"
895 "\n"
896 " if (n10[1][2] != 300.2)\n"
897 " color = error;\n"
898 "\n"
899 " if (n10[2][0] != 100.3)\n"
900 " color = error;\n"
901 "\n"
902 " if (n10[2][1] != 200.3)\n"
903 " color = error;\n"
904 "\n"
905 " if (n10[2][2] != 300.3)\n"
906 " color = error;\n"
907 "\n"
908 " if (n11[0][0] != 1000.1)\n"
909 " color = error;\n"
910 "\n"
911 " if (n11[0][1] != 2000.1)\n"
912 " color = error;\n"
913 "\n"
914 " if (n11[0][2] != 3000.1)\n"
915 " color = error;\n"
916 "\n"
917 " if (n11[1][0] != 1000.2)\n"
918 " color = error;\n"
919 "\n"
920 " if (n11[1][1] != 2000.2)\n"
921 " color = error;\n"
922 "\n"
923 " if (n11[1][2] != 3000.2)\n"
924 " color = error;\n"
925 "\n"
926 " if (n11[2][0] != 1000.3)\n"
927 " color = error;\n"
928 "\n"
929 " if (n11[2][1] != 2000.3)\n"
930 " color = error;\n"
931 "\n"
932 " if (n11[2][2] != 3000.3)\n"
933 " color = error;\n"
934 "\n"
935 #ifdef HAS_FP64_EXTENSION
936 " if (p != 17856.23456LF)\n"
937 " color = error;\n"
938 #endif
939 "\n"
940 " if (q != true)\n"
941 " color = error;\n"
942 "\n"
943 #ifdef HAS_FP64_EXTENSION
944 " if (r != dvec2(9567.123LF, 2345.63456LF))\n"
945 " color = error;\n"
946 #endif
947 "\n"
948 " if (s != 123)\n"
949 " color = error;\n"
950 "\n"
951 " if (t0 != 1.001)\n"
952 " color = error;\n"
953 "\n"
954 " if (v00 != ivec3(1,0,1))\n"
955 " color = error;\n"
956 "\n"
957 " if (v01 != ivec3(2,0,2))\n"
958 " color = error;\n"
959 "\n"
960 " if (v02 != ivec3(3,0,3))\n"
961 " color = error;\n"
962 "\n"
963 " if (w0 != 1)\n"
964 " color = error;\n"
965 "\n"
966 " if (t1 != 2.002)\n"
967 " color = error;\n"
968 "\n"
969 " if (v10 != ivec3(4,0,4))\n"
970 " color = error;\n"
971 "\n"
972 " if (v11 != ivec3(5,0,5))\n"
973 " color = error;\n"
974 "\n"
975 " if (v12 != ivec3(6,0,6))\n"
976 " color = error;\n"
977 "\n"
978 " if (w1 != 2)\n"
979 " color = error;\n"
980 "\n"
981 " if (t2 != 3.003)\n"
982 " color = error;\n"
983 "\n"
984 " if (v20 != ivec3(7,0,7))\n"
985 " color = error;\n"
986 "\n"
987 " if (v21 != ivec3(8,0,8))\n"
988 " color = error;\n"
989 "\n"
990 " if (v22 != ivec3(9,0,9))\n"
991 " color = error;\n"
992 "\n"
993 " if (w2 != 3)\n"
994 " color = error;\n"
995 "\n"
996 " if (t3 != 4.004)\n"
997 " color = error;\n"
998 "\n"
999 " if (v30 != ivec3(1,4,6))\n"
1000 " color = error;\n"
1001 "\n"
1002 " if (v31 != ivec3(2,5,7))\n"
1003 " color = error;\n"
1004 "\n"
1005 " if (v32 != ivec3(3,6,8))\n"
1006 " color = error;\n"
1007 "\n"
1008 " if (w3 != 4)\n"
1009 " color = error;\n"
1010 "\n"
1011 "\n"
1012 " vFragColor = color;\n"
1013 "}\n"
1014 "\n"
1017 return fp_program;