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