Tizen 2.1 base
[platform/upstream/libbullet.git] / Extras / RigidBodyGpuPipeline / opencl / opengl_interop / main.cpp
1 \r
2 //starts crashing when more than 32700 objects on my Geforce 260, unless _USE_SUB_DATA is defined (still unstable though)\r
3 //runs fine with fewer objects\r
4 \r
5 #define NUM_OBJECTS_X 327\r
6 #define NUM_OBJECTS_Y 10\r
7 #define NUM_OBJECTS_Z 10\r
8 //#define NUM_OBJECTS_Z 20\r
9 \r
10 //#define _USE_SUB_DATA\r
11 \r
12 //#define NUM_OBJECTS_X 100\r
13 //#define NUM_OBJECTS_Y 100\r
14 //#define NUM_OBJECTS_Z 100\r
15 \r
16 ///RECREATE_CL_AND_SHADERS_ON_RESIZE will delete and re-create OpenCL and GLSL shaders/buffers at each resize\r
17 //#define RECREATE_CL_AND_SHADERS_ON_RESIZE\r
18 \r
19 ///\r
20 /// OpenCL - OpenGL interop example. Updating transforms of many cubes on GPU, without going through main memory/using the PCIe bus\r
21 /// Create all OpenGL resources AFTER create OpenCL context!\r
22 ///\r
23 \r
24 \r
25 #include <GL/glew.h>\r
26 #include <stdio.h>\r
27 \r
28 #include "btGlutInclude.h"\r
29 #include "btStopwatch.h"\r
30 \r
31 \r
32 #include "btVector3.h"\r
33 #include "btQuaternion.h"\r
34 #include "btMatrix3x3.h"\r
35 static float angle(0);\r
36 \r
37 #include <assert.h>\r
38 \r
39 #ifdef _WIN32\r
40 #include <windows.h>\r
41 #endif\r
42 \r
43 //OpenCL stuff\r
44 #include "../basic_initialize/btOpenCLUtils.h"\r
45 #include "btOpenCLGLInteropBuffer.h"\r
46 \r
47 cl_context                      g_cxMainContext;\r
48 cl_command_queue        g_cqCommandQue;\r
49 cl_device_id            g_device;\r
50 static const size_t workGroupSize = 128;\r
51 \r
52 \r
53 btOpenCLGLInteropBuffer* g_interopBuffer = 0;\r
54 cl_kernel g_interopKernel;\r
55 \r
56 bool useCPU = false;\r
57 bool printStats = false;\r
58 bool runOpenCLKernels = true;\r
59 \r
60 #define MSTRINGIFY(A) #A\r
61 static char* interopKernelString =\r
62 #include "interopKernel.cl"\r
63 \r
64 btStopwatch gStopwatch;\r
65 int m_glutScreenWidth = 640;\r
66 int m_glutScreenHeight= 480;\r
67 \r
68 bool m_ortho = false;\r
69 \r
70 static GLuint               instancingShader;        // The instancing renderer\r
71 static GLuint               cube_vao;\r
72 static GLuint               cube_vbo;\r
73 static GLuint               index_vbo;\r
74 static GLuint                           m_texturehandle;\r
75 \r
76 static bool                 done = false;\r
77 static GLint                angle_loc = 0;\r
78 static GLint ModelViewMatrix;\r
79 static GLint ProjectionMatrix;\r
80 \r
81 \r
82 static GLint                uniform_texture_diffuse = 0;\r
83 \r
84 //used for dynamic loading from disk (default switched off)\r
85 #define MAX_SHADER_LENGTH   8192\r
86 static GLubyte shaderText[MAX_SHADER_LENGTH];\r
87 \r
88 static const char* vertexShader= \\r
89 "#version 330\n"\r
90 "precision highp float;\n"\r
91 "\n"\r
92 "\n"\r
93 "\n"\r
94 "layout (location = 0) in vec4 position;\n"\r
95 "layout (location = 1) in vec4 instance_position;\n"\r
96 "layout (location = 2) in vec4 instance_quaternion;\n"\r
97 "layout (location = 3) in vec2 uvcoords;\n"\r
98 "layout (location = 4) in vec3 vertexnormal;\n"\r
99 "\n"\r
100 "\n"\r
101 "uniform float angle = 0.0;\n"\r
102 "uniform mat4 ModelViewMatrix;\n"\r
103 "uniform mat4 ProjectionMatrix;\n"\r
104 "\n"\r
105 "out Fragment\n"\r
106 "{\n"\r
107 "     vec4 color;\n"\r
108 "} fragment;\n"\r
109 "\n"\r
110 "out Vert\n"\r
111 "{\n"\r
112 "       vec2 texcoord;\n"\r
113 "} vert;\n"\r
114 "\n"\r
115 "\n"\r
116 "vec4 quatMul ( in vec4 q1, in vec4 q2 )\n"\r
117 "{\n"\r
118 "    vec3  im = q1.w * q2.xyz + q1.xyz * q2.w + cross ( q1.xyz, q2.xyz );\n"\r
119 "    vec4  dt = q1 * q2;\n"\r
120 "    float re = dot ( dt, vec4 ( -1.0, -1.0, -1.0, 1.0 ) );\n"\r
121 "    return vec4 ( im, re );\n"\r
122 "}\n"\r
123 "\n"\r
124 "vec4 quatFromAxisAngle(vec4 axis, in float angle)\n"\r
125 "{\n"\r
126 "    float cah = cos(angle*0.5);\n"\r
127 "    float sah = sin(angle*0.5);\n"\r
128 "       float d = inversesqrt(dot(axis,axis));\n"\r
129 "       vec4 q = vec4(axis.x*sah*d,axis.y*sah*d,axis.z*sah*d,cah);\n"\r
130 "       return q;\n"\r
131 "}\n"\r
132 "//\n"\r
133 "// vector rotation via quaternion\n"\r
134 "//\n"\r
135 "vec4 quatRotate3 ( in vec3 p, in vec4 q )\n"\r
136 "{\n"\r
137 "    vec4 temp = quatMul ( q, vec4 ( p, 0.0 ) );\n"\r
138 "    return quatMul ( temp, vec4 ( -q.x, -q.y, -q.z, q.w ) );\n"\r
139 "}\n"\r
140 "vec4 quatRotate ( in vec4 p, in vec4 q )\n"\r
141 "{\n"\r
142 "    vec4 temp = quatMul ( q, p );\n"\r
143 "    return quatMul ( temp, vec4 ( -q.x, -q.y, -q.z, q.w ) );\n"\r
144 "}\n"\r
145 "\n"\r
146 "out vec3 lightDir,normal,ambient;\n"\r
147 "\n"\r
148 "void main(void)\n"\r
149 "{\n"\r
150 "       vec4 q = instance_quaternion;\n"\r
151 "       ambient = vec3(0.2,0.2,0.2);\n"\r
152 "               \n"\r
153 "               \n"\r
154 "       vec4 local_normal = (quatRotate3( vertexnormal,q));\n"\r
155 "       vec3 light_pos = vec3(1000,1000,1000);\n"\r
156 "       normal = normalize(ModelViewMatrix * local_normal).xyz;\n"\r
157 "\n"\r
158 "       lightDir = normalize(light_pos);//gl_LightSource[0].position.xyz));\n"\r
159 "//     lightDir = normalize(vec3(gl_LightSource[0].position));\n"\r
160 "               \n"\r
161 "       vec4 axis = vec4(1,1,1,0);\n"\r
162 "       vec4 localcoord = quatRotate3( position.xyz,q);\n"\r
163 "       vec4 vertexPos = ProjectionMatrix * ModelViewMatrix *(instance_position+localcoord);\n"\r
164 "\n"\r
165 "       gl_Position = vertexPos;\n"\r
166 "       \n"\r
167 "//     fragment.color = instance_color;\n"\r
168 "       vert.texcoord = uvcoords;\n"\r
169 "}\n"\r
170 ;\r
171 \r
172 \r
173 static const char* fragmentShader= \\r
174 "#version 330\n"\r
175 "precision highp float;\n"\r
176 "\n"\r
177 "in Fragment\n"\r
178 "{\n"\r
179 "     vec4 color;\n"\r
180 "} fragment;\n"\r
181 "\n"\r
182 "in Vert\n"\r
183 "{\n"\r
184 "       vec2 texcoord;\n"\r
185 "} vert;\n"\r
186 "\n"\r
187 "uniform sampler2D Diffuse;\n"\r
188 "\n"\r
189 "in vec3 lightDir,normal,ambient;\n"\r
190 "\n"\r
191 "out vec4 color;\n"\r
192 "\n"\r
193 "void main_textured(void)\n"\r
194 "{\n"\r
195 "    color = texture2D(Diffuse,vert.texcoord);//fragment.color;\n"\r
196 "}\n"\r
197 "\n"\r
198 "void main(void)\n"\r
199 "{\n"\r
200 "    vec4 texel = texture2D(Diffuse,vert.texcoord);//fragment.color;\n"\r
201 "       vec3 ct,cf;\n"\r
202 "       float intensity,at,af;\n"\r
203 "       intensity = max(dot(lightDir,normalize(normal)),0.0);\n"\r
204 "       cf = intensity*vec3(1.0,1.0,1.0);//intensity * (gl_FrontMaterial.diffuse).rgb+ambient;//gl_FrontMaterial.ambient.rgb;\n"\r
205 "       af = 1.0;\n"\r
206 "               \n"\r
207 "       ct = texel.rgb;\n"\r
208 "       at = texel.a;\n"\r
209 "               \n"\r
210 "       color  = vec4(ct * cf, at * af);        \n"\r
211 "}\n"\r
212 ;\r
213 \r
214 \r
215 // Load the shader from the source text\r
216 void gltLoadShaderSrc(const char *szShaderSrc, GLuint shader)\r
217 {\r
218         GLchar *fsStringPtr[1];\r
219 \r
220         fsStringPtr[0] = (GLchar *)szShaderSrc;\r
221         glShaderSource(shader, 1, (const GLchar **)fsStringPtr, NULL);\r
222 }\r
223 \r
224 \r
225 ////////////////////////////////////////////////////////////////\r
226 // Load the shader from the specified file. Returns false if the\r
227 // shader could not be loaded\r
228 bool gltLoadShaderFile(const char *szFile, GLuint shader)\r
229 {\r
230         GLint shaderLength = 0;\r
231         FILE *fp;\r
232 \r
233         // Open the shader file\r
234         fp = fopen(szFile, "r");\r
235         if(fp != NULL)\r
236         {\r
237                 // See how long the file is\r
238                 while (fgetc(fp) != EOF)\r
239                         shaderLength++;\r
240 \r
241                 // Allocate a block of memory to send in the shader\r
242                 assert(shaderLength < MAX_SHADER_LENGTH);   // make me bigger!\r
243                 if(shaderLength > MAX_SHADER_LENGTH)\r
244                 {\r
245                         fclose(fp);\r
246                         return false;\r
247                 }\r
248 \r
249                 // Go back to beginning of file\r
250                 rewind(fp);\r
251 \r
252                 // Read the whole file in\r
253                 if (shaderText != NULL)\r
254                         fread(shaderText, 1, shaderLength, fp);\r
255 \r
256                 // Make sure it is null terminated and close the file\r
257                 shaderText[shaderLength] = '\0';\r
258                 fclose(fp);\r
259         }\r
260         else\r
261                 return false;    \r
262 \r
263         //      printf(shaderText);\r
264         // Load the string\r
265         gltLoadShaderSrc((const char *)shaderText, shader);\r
266 \r
267         return true;\r
268 }   \r
269 \r
270 \r
271 /////////////////////////////////////////////////////////////////\r
272 // Load a pair of shaders, compile, and link together. Specify the complete\r
273 // file path for each shader. Note, there is no support for\r
274 // just loading say a vertex program... you have to do both.\r
275 GLuint gltLoadShaderPair(const char *szVertexProg, const char *szFragmentProg, bool loadFromFile)\r
276 {\r
277         // Temporary Shader objects\r
278         GLuint hVertexShader;\r
279         GLuint hFragmentShader; \r
280         GLuint hReturn = 0;   \r
281         GLint testVal;\r
282 \r
283         // Create shader objects\r
284         hVertexShader = glCreateShader(GL_VERTEX_SHADER);\r
285         hFragmentShader = glCreateShader(GL_FRAGMENT_SHADER);\r
286 \r
287         if (loadFromFile)\r
288         {\r
289 \r
290                 if(gltLoadShaderFile(szVertexProg, hVertexShader) == false)\r
291                 {\r
292                         glDeleteShader(hVertexShader);\r
293                         glDeleteShader(hFragmentShader);\r
294                         return (GLuint)NULL;\r
295                 }\r
296 \r
297                 if(gltLoadShaderFile(szFragmentProg, hFragmentShader) == false)\r
298                 {\r
299                         glDeleteShader(hVertexShader);\r
300                         glDeleteShader(hFragmentShader);\r
301                         return (GLuint)NULL;\r
302                 }\r
303         } else\r
304         {\r
305                 gltLoadShaderSrc(vertexShader, hVertexShader);\r
306                 gltLoadShaderSrc(fragmentShader, hFragmentShader);\r
307         }\r
308         // Compile them\r
309         glCompileShader(hVertexShader);\r
310         glCompileShader(hFragmentShader);\r
311 \r
312         // Check for errors\r
313         glGetShaderiv(hVertexShader, GL_COMPILE_STATUS, &testVal);\r
314         if(testVal == GL_FALSE)\r
315         {\r
316                          char temp[256] = "";\r
317                         glGetShaderInfoLog( hVertexShader, 256, NULL, temp);\r
318                         fprintf( stderr, "Compile failed:\n%s\n", temp);\r
319                         assert(0);\r
320                         exit(0);\r
321                 glDeleteShader(hVertexShader);\r
322                 glDeleteShader(hFragmentShader);\r
323                 return (GLuint)NULL;\r
324         }\r
325 \r
326         glGetShaderiv(hFragmentShader, GL_COMPILE_STATUS, &testVal);\r
327         if(testVal == GL_FALSE)\r
328         {\r
329                  char temp[256] = "";\r
330                         glGetShaderInfoLog( hFragmentShader, 256, NULL, temp);\r
331                         fprintf( stderr, "Compile failed:\n%s\n", temp);\r
332                         assert(0);\r
333                         exit(0);\r
334                 glDeleteShader(hVertexShader);\r
335                 glDeleteShader(hFragmentShader);\r
336                 return (GLuint)NULL;\r
337         }\r
338 \r
339         // Link them - assuming it works...\r
340         hReturn = glCreateProgram();\r
341         glAttachShader(hReturn, hVertexShader);\r
342         glAttachShader(hReturn, hFragmentShader);\r
343 \r
344         glLinkProgram(hReturn);\r
345 \r
346         // These are no longer needed\r
347         glDeleteShader(hVertexShader);\r
348         glDeleteShader(hFragmentShader);  \r
349 \r
350         // Make sure link worked too\r
351         glGetProgramiv(hReturn, GL_LINK_STATUS, &testVal);\r
352         if(testVal == GL_FALSE)\r
353         {\r
354                 glDeleteProgram(hReturn);\r
355                 return (GLuint)NULL;\r
356         }\r
357 \r
358         return hReturn;  \r
359 }   \r
360 \r
361 ///position xyz, unused w, normal, uv\r
362 static const GLfloat cube_vertices[] =\r
363 {\r
364         -1.0f, -1.0f, 1.0f, 0.0f,       0,0,1,  0,0,//0\r
365         1.0f, -1.0f, 1.0f, 0.0f,        0,0,1,  1,0,//1\r
366         1.0f,  1.0f, 1.0f, 0.0f,        0,0,1,  1,1,//2\r
367         -1.0f,  1.0f, 1.0f, 0.0f,       0,0,1,  0,1     ,//3\r
368 \r
369         -1.0f, -1.0f, -1.0f, 1.0f,      0,0,-1, 0,0,//4\r
370         1.0f, -1.0f, -1.0f, 1.0f,       0,0,-1, 1,0,//5\r
371         1.0f,  1.0f, -1.0f, 1.0f,       0,0,-1, 1,1,//6\r
372         -1.0f,  1.0f, -1.0f, 1.0f,      0,0,-1, 0,1,//7\r
373 \r
374         -1.0f, -1.0f, -1.0f, 1.0f,      -1,0,0, 0,0,\r
375         -1.0f, 1.0f, -1.0f, 1.0f,       -1,0,0, 1,0,\r
376         -1.0f,  1.0f, 1.0f, 1.0f,       -1,0,0, 1,1,\r
377         -1.0f,  -1.0f, 1.0f, 1.0f,      -1,0,0, 0,1,\r
378 \r
379         1.0f, -1.0f, -1.0f, 1.0f,       1,0,0,  0,0,\r
380         1.0f, 1.0f, -1.0f, 1.0f,        1,0,0,  1,0,\r
381         1.0f,  1.0f, 1.0f, 1.0f,        1,0,0,  1,1,\r
382         1.0f,  -1.0f, 1.0f, 1.0f,       1,0,0,  0,1,\r
383 \r
384         -1.0f, -1.0f,  -1.0f, 1.0f,     0,-1,0, 0,0,\r
385         -1.0f, -1.0f, 1.0f, 1.0f,       0,-1,0, 1,0,\r
386         1.0f, -1.0f,  1.0f, 1.0f,       0,-1,0, 1,1,\r
387         1.0f,-1.0f,  -1.0f,  1.0f,      0,-1,0, 0,1,\r
388 \r
389         -1.0f, 1.0f,  -1.0f, 1.0f,      0,1,0,  0,0,\r
390         -1.0f, 1.0f, 1.0f, 1.0f,        0,1,0,  1,0,\r
391         1.0f, 1.0f,  1.0f, 1.0f,        0,1,0,  1,1,\r
392         1.0f,1.0f,  -1.0f,  1.0f,       0,1,0,  0,1,\r
393 };\r
394 \r
395 static const int cube_indices[]=\r
396 {\r
397         0,1,2,0,2,3,//ground face\r
398         4,5,6,4,6,7,//top face\r
399         8,9,10,8,10,11,\r
400         12,13,14,12,14,15,\r
401         16,17,18,16,18,19,\r
402         20,21,22,20,22,23\r
403 };\r
404 \r
405 \r
406 \r
407 \r
408 \r
409 void DeleteCL()\r
410 {\r
411         clReleaseContext(g_cxMainContext);\r
412         clReleaseCommandQueue(g_cqCommandQue);\r
413 }\r
414 \r
415 void InitCL()\r
416 {\r
417         void* glCtx=0;\r
418         void* glDC = 0;\r
419 \r
420 #ifdef _WIN32\r
421         glCtx = wglGetCurrentContext();\r
422 #else //!_WIN32\r
423         GLXContext glCtx = glXGetCurrentContext();\r
424 #endif //!_WIN32\r
425         glDC = wglGetCurrentDC();\r
426 \r
427         int ciErrNum = 0;\r
428         cl_device_type deviceType = CL_DEVICE_TYPE_ALL;//CPU;\r
429         g_cxMainContext = btOpenCLUtils::createContextFromType(deviceType, &ciErrNum, glCtx, glDC);\r
430         oclCHECKERROR(ciErrNum, CL_SUCCESS);\r
431 \r
432         int numDev = btOpenCLUtils::getNumDevices(g_cxMainContext);\r
433 \r
434         if (numDev>0)\r
435         {\r
436                 g_device= btOpenCLUtils::getDevice(g_cxMainContext,0);\r
437                 btOpenCLDeviceInfo clInfo;\r
438                 btOpenCLUtils::getDeviceInfo(g_device,clInfo);\r
439                 btOpenCLUtils::printDeviceInfo(g_device);\r
440                 // create a command-queue\r
441                 g_cqCommandQue = clCreateCommandQueue(g_cxMainContext, g_device, 0, &ciErrNum);\r
442                 oclCHECKERROR(ciErrNum, CL_SUCCESS);\r
443                 //normally you would create and execute kernels using this command queue\r
444 \r
445         }\r
446 \r
447 \r
448 }\r
449 \r
450 #define NUM_OBJECTS (NUM_OBJECTS_X*NUM_OBJECTS_Y*NUM_OBJECTS_Z)\r
451 #define POSITION_BUFFER_SIZE (NUM_OBJECTS*sizeof(float)*4)\r
452 #define ORIENTATION_BUFFER_SIZE (NUM_OBJECTS*sizeof(float)*4)\r
453 \r
454 \r
455 GLfloat* instance_positions_ptr = 0;\r
456 GLfloat* instance_quaternion_ptr = 0;\r
457 \r
458 void DeleteShaders()\r
459 {\r
460         glDeleteVertexArrays(1, &cube_vao);\r
461         glDeleteBuffers(1,&index_vbo);\r
462         glDeleteBuffers(1,&cube_vbo);\r
463         glDeleteProgram(instancingShader);\r
464 }\r
465 \r
466 void writeTransforms()\r
467 {\r
468 \r
469 \r
470         glFlush();\r
471         char* bla =  (char*)glMapBuffer( GL_ARRAY_BUFFER,GL_READ_WRITE);//GL_WRITE_ONLY\r
472 \r
473         float* positions = (float*)(bla+sizeof(cube_vertices));\r
474         float* orientations = (float*)(bla+sizeof(cube_vertices) + POSITION_BUFFER_SIZE);\r
475         //      positions[0]+=0.001f;\r
476 \r
477         static int offset=0;\r
478         //offset++;\r
479 \r
480         static btVector3 axis(1,0,0);\r
481         angle += 0.01f;\r
482         int index=0;\r
483         btQuaternion orn(axis,angle);\r
484         for (int i=0;i<NUM_OBJECTS_X;i++)\r
485         {\r
486                 for (int j=0;j<NUM_OBJECTS_Y;j++)\r
487                 {\r
488                         for (int k=0;k<NUM_OBJECTS_Z;k++)\r
489                         {\r
490                                 //if (!((index+offset)%15))\r
491                                 {\r
492                                         instance_positions_ptr[index*4+1]-=0.01f;\r
493                                         positions[index*4]=instance_positions_ptr[index*4];\r
494                                         positions[index*4+1]=instance_positions_ptr[index*4+1];\r
495                                         positions[index*4+2]=instance_positions_ptr[index*4+2];\r
496                                         positions[index*4+3]=instance_positions_ptr[index*4+3];\r
497 \r
498                                         orientations[index*4] = orn[0];\r
499                                         orientations[index*4+1] = orn[1];\r
500                                         orientations[index*4+2] = orn[2];\r
501                                         orientations[index*4+3] = orn[3];\r
502                                 }\r
503                                 //                              memcpy((void*)&orientations[index*4],orn,sizeof(btQuaternion));\r
504                                 index++;\r
505                         }\r
506                 }\r
507         }\r
508 \r
509         glUnmapBuffer( GL_ARRAY_BUFFER);\r
510         //if this glFinish is removed, the animation is not always working/blocks\r
511         //@todo: figure out why\r
512         glFlush();\r
513 }\r
514 \r
515 void InitShaders()\r
516 {\r
517         bool loadFromFile = false;\r
518         instancingShader = gltLoadShaderPair("instancing.vs","instancing.fs", loadFromFile);\r
519 \r
520         glLinkProgram(instancingShader);\r
521         glUseProgram(instancingShader);\r
522         angle_loc = glGetUniformLocation(instancingShader, "angle");\r
523         ModelViewMatrix = glGetUniformLocation(instancingShader, "ModelViewMatrix");\r
524         ProjectionMatrix = glGetUniformLocation(instancingShader, "ProjectionMatrix");\r
525         uniform_texture_diffuse = glGetUniformLocation(instancingShader, "Diffuse");\r
526 \r
527         GLuint offset = 0;\r
528 \r
529 \r
530         glGenBuffers(1, &cube_vbo);\r
531         glBindBuffer(GL_ARRAY_BUFFER, cube_vbo);\r
532 \r
533         instance_positions_ptr = (GLfloat*)new float[NUM_OBJECTS*4];\r
534         instance_quaternion_ptr = (GLfloat*)new float[NUM_OBJECTS*4];\r
535         int index=0;\r
536         for (int i=0;i<NUM_OBJECTS_X;i++)\r
537         {\r
538                 for (int j=0;j<NUM_OBJECTS_Y;j++)\r
539                 {\r
540                         for (int k=0;k<NUM_OBJECTS_Z;k++)\r
541                         {\r
542                                 instance_positions_ptr[index*4]=-(i-NUM_OBJECTS_X/2)*10;\r
543                                 instance_positions_ptr[index*4+1]=-(j-NUM_OBJECTS_Y/2)*10;\r
544                                 instance_positions_ptr[index*4+2]=-k*10;\r
545                                 instance_positions_ptr[index*4+3]=1;\r
546 \r
547                                 instance_quaternion_ptr[index*4]=0;\r
548                                 instance_quaternion_ptr[index*4+1]=0;\r
549                                 instance_quaternion_ptr[index*4+2]=0;\r
550                                 instance_quaternion_ptr[index*4+3]=1;\r
551                                 index++;\r
552                         }\r
553                 }\r
554         }\r
555 \r
556         int size = sizeof(cube_vertices)  + POSITION_BUFFER_SIZE+ORIENTATION_BUFFER_SIZE;\r
557 \r
558         char* bla = (char*)malloc(size);\r
559         int szc = sizeof(cube_vertices);\r
560         memcpy(bla,&cube_vertices[0],szc);\r
561         memcpy(bla+sizeof(cube_vertices),instance_positions_ptr,POSITION_BUFFER_SIZE);\r
562         memcpy(bla+sizeof(cube_vertices)+POSITION_BUFFER_SIZE,instance_quaternion_ptr,ORIENTATION_BUFFER_SIZE);\r
563 \r
564         glBufferData(GL_ARRAY_BUFFER, size, bla, GL_DYNAMIC_DRAW);//GL_STATIC_DRAW);\r
565 \r
566         ///initialize parts of the buffer\r
567 #ifdef _USE_SUB_DATA\r
568         glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(cube_vertices)+ 16384, bla);//cube_vertices);\r
569 #endif\r
570 \r
571         char* dest=  (char*)glMapBuffer( GL_ARRAY_BUFFER,GL_WRITE_ONLY);//GL_WRITE_ONLY\r
572         memcpy(dest,cube_vertices,sizeof(cube_vertices));\r
573         //memcpy(dest+sizeof(cube_vertices),instance_colors,sizeof(instance_colors));\r
574         glUnmapBuffer( GL_ARRAY_BUFFER);\r
575 \r
576 \r
577 \r
578         writeTransforms();\r
579 \r
580         /*\r
581         glBufferSubData(GL_ARRAY_BUFFER, sizeof(cube_vertices) + sizeof(instance_colors), POSITION_BUFFER_SIZE, instance_positions_ptr);\r
582         glBufferSubData(GL_ARRAY_BUFFER, sizeof(cube_vertices) + sizeof(instance_colors)+POSITION_BUFFER_SIZE,ORIENTATION_BUFFER_SIZE , instance_quaternion_ptr);\r
583         */\r
584 \r
585         glGenVertexArrays(1, &cube_vao);\r
586         glBindVertexArray(cube_vao);\r
587         glBindBuffer(GL_ARRAY_BUFFER, cube_vbo);\r
588         glBindVertexArray(0);\r
589 \r
590         glGenBuffers(1, &index_vbo);\r
591         int indexBufferSize = sizeof(cube_indices);\r
592         glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_vbo);\r
593 \r
594         glBufferData(GL_ELEMENT_ARRAY_BUFFER, indexBufferSize, NULL, GL_STATIC_DRAW);\r
595         glBufferSubData(GL_ELEMENT_ARRAY_BUFFER,0,indexBufferSize,cube_indices);\r
596 \r
597         glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);\r
598         glBindBuffer(GL_ARRAY_BUFFER,0);\r
599         glBindVertexArray(0);\r
600 \r
601 }\r
602 \r
603 \r
604 \r
605 void updateCamera() {\r
606 \r
607         float m_ele = 0;\r
608         float m_azi=0;\r
609 \r
610         btVector3 m_cameraPosition(12,20,12);\r
611         btVector3 m_cameraTargetPosition(0,10,0);\r
612 \r
613         btVector3 m_cameraUp(0,1,0);\r
614         int m_forwardAxis=2;\r
615         btScalar m_cameraDistance = 130;\r
616 \r
617         glMatrixMode(GL_PROJECTION);\r
618         glLoadIdentity();\r
619 \r
620 \r
621         float m_frustumZNear=1;\r
622         float m_frustumZFar=1000;\r
623 \r
624         if (m_glutScreenWidth == 0 && m_glutScreenHeight == 0)\r
625                 return;\r
626 \r
627         float aspect;\r
628         btVector3 extents;\r
629 \r
630         if (m_glutScreenWidth > m_glutScreenHeight) \r
631         {\r
632                 aspect = m_glutScreenWidth / (float)m_glutScreenHeight;\r
633                 extents.setValue(aspect * 1.0f, 1.0f,0);\r
634         } else \r
635         {\r
636                 aspect = m_glutScreenHeight / (float)m_glutScreenWidth;\r
637                 extents.setValue(1.0f, aspect*1.f,0);\r
638         }\r
639 \r
640 \r
641         if (m_ortho)\r
642         {\r
643                 // reset matrix\r
644                 glLoadIdentity();\r
645                 extents *= m_cameraDistance;\r
646                 btVector3 lower = m_cameraTargetPosition - extents;\r
647                 btVector3 upper = m_cameraTargetPosition + extents;\r
648                 glOrtho(lower.getX(), upper.getX(), lower.getY(), upper.getY(),-1000,1000);\r
649 \r
650                 glMatrixMode(GL_MODELVIEW);\r
651                 glLoadIdentity();\r
652         } else\r
653         {\r
654                 if (m_glutScreenWidth > m_glutScreenHeight) \r
655                 {\r
656                         glFrustum (-aspect * m_frustumZNear, aspect * m_frustumZNear, -m_frustumZNear, m_frustumZNear, m_frustumZNear, m_frustumZFar);\r
657                 } else \r
658                 {\r
659                         glFrustum (-aspect * m_frustumZNear, aspect * m_frustumZNear, -m_frustumZNear, m_frustumZNear, m_frustumZNear, m_frustumZFar);\r
660                 }\r
661                 glMatrixMode(GL_MODELVIEW);\r
662                 glLoadIdentity();\r
663                 gluLookAt(m_cameraPosition[0], m_cameraPosition[1], m_cameraPosition[2], \r
664                         m_cameraTargetPosition[0], m_cameraTargetPosition[1], m_cameraTargetPosition[2], \r
665                         m_cameraUp.getX(),m_cameraUp.getY(),m_cameraUp.getZ());\r
666         }\r
667 \r
668 }\r
669 \r
670 \r
671 \r
672 void myinit()\r
673 {\r
674 \r
675 \r
676         //      GLfloat light_ambient[] = { btScalar(0.2), btScalar(0.2), btScalar(0.2), btScalar(1.0) };\r
677         GLfloat light_ambient[] = { btScalar(1.0), btScalar(1.2), btScalar(0.2), btScalar(1.0) };\r
678 \r
679         GLfloat light_diffuse[] = { btScalar(1.0), btScalar(1.0), btScalar(1.0), btScalar(1.0) };\r
680         GLfloat light_specular[] = { btScalar(1.0), btScalar(1.0), btScalar(1.0), btScalar(1.0 )};\r
681         /*      light_position is NOT default value     */\r
682         GLfloat light_position0[] = { btScalar(1000.0), btScalar(1000.0), btScalar(1000.0), btScalar(0.0 )};\r
683         GLfloat light_position1[] = { btScalar(-1.0), btScalar(-10.0), btScalar(-1.0), btScalar(0.0) };\r
684 \r
685         glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient);\r
686         glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);\r
687         glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular);\r
688         glLightfv(GL_LIGHT0, GL_POSITION, light_position0);\r
689 \r
690         glLightfv(GL_LIGHT1, GL_AMBIENT, light_ambient);\r
691         glLightfv(GL_LIGHT1, GL_DIFFUSE, light_diffuse);\r
692         glLightfv(GL_LIGHT1, GL_SPECULAR, light_specular);\r
693         glLightfv(GL_LIGHT1, GL_POSITION, light_position1);\r
694 \r
695         glEnable(GL_LIGHTING);\r
696         glEnable(GL_LIGHT0);\r
697         glEnable(GL_LIGHT1);\r
698 \r
699 \r
700         //      glShadeModel(GL_FLAT);//GL_SMOOTH);\r
701         glShadeModel(GL_SMOOTH);\r
702 \r
703         glEnable(GL_DEPTH_TEST);\r
704         glDepthFunc(GL_LESS);\r
705 \r
706         glClearColor(float(0.7),float(0.7),float(0.7),float(0));\r
707         glEnable(GL_LIGHTING);\r
708         glEnable(GL_LIGHT0);\r
709 \r
710 \r
711         static bool m_textureenabled = true;\r
712         static bool m_textureinitialized = false;\r
713 \r
714 \r
715         if(m_textureenabled)\r
716         {\r
717                 if(!m_textureinitialized)\r
718                 {\r
719                         glActiveTexture(GL_TEXTURE0);\r
720 \r
721                         GLubyte*        image=new GLubyte[256*256*3];\r
722                         for(int y=0;y<256;++y)\r
723                         {\r
724                                 const int       t=y>>5;\r
725                                 GLubyte*        pi=image+y*256*3;\r
726                                 for(int x=0;x<256;++x)\r
727                                 {\r
728                                         const int               s=x>>5;\r
729                                         const GLubyte   b=180;                                  \r
730                                         GLubyte                 c=b+((s+t&1)&1)*(255-b);\r
731                                         pi[0]=255;\r
732                                         pi[1]=c;\r
733                                         pi[2]=c;\r
734                                         pi+=3;\r
735                                 }\r
736                         }\r
737 \r
738                         glGenTextures(1,(GLuint*)&m_texturehandle);\r
739                         glBindTexture(GL_TEXTURE_2D,m_texturehandle);\r
740                         glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_MODULATE);\r
741                         glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_LINEAR);\r
742                         glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR_MIPMAP_LINEAR);\r
743                         glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT);\r
744                         glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT);\r
745                         gluBuild2DMipmaps(GL_TEXTURE_2D,3,256,256,GL_RGB,GL_UNSIGNED_BYTE,image);\r
746                         delete[] image;\r
747                         m_textureinitialized=true;\r
748                 }\r
749                 //              glMatrixMode(GL_TEXTURE);\r
750                 //              glLoadIdentity();\r
751                 //              glMatrixMode(GL_MODELVIEW);\r
752 \r
753                 glEnable(GL_TEXTURE_2D);\r
754                 glBindTexture(GL_TEXTURE_2D,m_texturehandle);\r
755 \r
756         } else\r
757         {\r
758                 glDisable(GL_TEXTURE_2D);\r
759         }\r
760 \r
761         glEnable(GL_COLOR_MATERIAL);\r
762 \r
763 \r
764         //        glEnable(GL_CULL_FACE);\r
765         //        glCullFace(GL_BACK);\r
766 }\r
767 \r
768 //#pragma optimize( "g", off )\r
769 \r
770 void updatePos()\r
771 {\r
772 \r
773 \r
774         if (useCPU)\r
775         {\r
776                 int index=0;\r
777                 for (int i=0;i<NUM_OBJECTS_X;i++)\r
778                 {\r
779                         for (int j=0;j<NUM_OBJECTS_Y;j++)\r
780                         {\r
781                                 for (int k=0;k<NUM_OBJECTS_Z;k++)\r
782                                 {\r
783                                         //if (!((index+offset)%15))\r
784                                         {\r
785                                                 instance_positions_ptr[index*4+1]-=0.01f;\r
786                                         }\r
787                                 }\r
788                         }\r
789                 }\r
790                 writeTransforms();\r
791 \r
792         } \r
793         else\r
794         {\r
795 \r
796                 glFinish();\r
797                 cl_mem clBuffer = g_interopBuffer->getCLBUffer();\r
798                 cl_int ciErrNum = CL_SUCCESS;\r
799                 ciErrNum = clEnqueueAcquireGLObjects(g_cqCommandQue, 1, &clBuffer, 0, 0, NULL);\r
800                 oclCHECKERROR(ciErrNum, CL_SUCCESS);\r
801                 if (runOpenCLKernels)\r
802                 {\r
803                         int numObjects = NUM_OBJECTS;\r
804                         int offset = (sizeof(cube_vertices) )/4;\r
805 \r
806                         ciErrNum = clSetKernelArg(g_interopKernel, 0, sizeof(int), &offset);\r
807                         ciErrNum = clSetKernelArg(g_interopKernel, 1, sizeof(int), &numObjects);\r
808                         ciErrNum = clSetKernelArg(g_interopKernel, 2, sizeof(cl_mem), (void*)&clBuffer );\r
809                         size_t  numWorkItems = workGroupSize*((NUM_OBJECTS + (workGroupSize-1)) / workGroupSize);\r
810                         ciErrNum = clEnqueueNDRangeKernel(g_cqCommandQue, g_interopKernel, 1, NULL, &numWorkItems, &workGroupSize,0 ,0 ,0);\r
811                         oclCHECKERROR(ciErrNum, CL_SUCCESS);\r
812                 }\r
813                 ciErrNum = clEnqueueReleaseGLObjects(g_cqCommandQue, 1, &clBuffer, 0, 0, 0);\r
814                 oclCHECKERROR(ciErrNum, CL_SUCCESS);\r
815                 clFinish(g_cqCommandQue);\r
816 \r
817         }\r
818 \r
819 }\r
820 //#pragma optimize( "g", on )\r
821 \r
822 void RenderScene(void)\r
823 {\r
824 \r
825 #if 0\r
826         float modelview[20]={0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9};\r
827         // get the current modelview matrix\r
828         glGetFloatv(GL_MODELVIEW_MATRIX , modelview);\r
829         float projection[20]={0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9};\r
830         glGetFloatv(GL_PROJECTION_MATRIX, projection);\r
831 #endif\r
832 \r
833         myinit();\r
834 \r
835         updateCamera();\r
836 \r
837         glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); \r
838 \r
839         //render coordinate system\r
840         glBegin(GL_LINES);\r
841         glColor3f(1,0,0);\r
842         glVertex3f(0,0,0);\r
843         glVertex3f(1,0,0);\r
844         glColor3f(0,1,0);\r
845         glVertex3f(0,0,0);\r
846         glVertex3f(0,1,0);\r
847         glColor3f(0,0,1);\r
848         glVertex3f(0,0,0);\r
849         glVertex3f(0,0,1);\r
850         glEnd();\r
851 \r
852         //do a finish, to make sure timings are clean\r
853         //      glFinish();\r
854 \r
855         float start = gStopwatch.getTimeMilliseconds();\r
856 \r
857         //      glBindBuffer(GL_ARRAY_BUFFER, 0);\r
858         glBindBuffer(GL_ARRAY_BUFFER, cube_vbo);\r
859         glFlush();\r
860         updatePos();\r
861 \r
862         float stop = gStopwatch.getTimeMilliseconds();\r
863         gStopwatch.reset();\r
864 \r
865         if (printStats)\r
866         {\r
867                 printf("updatePos=%f ms on ",stop-start);\r
868 \r
869                 if (useCPU)\r
870                 {\r
871                         printf("CPU \n");\r
872                 } else\r
873                 {\r
874                         printf("OpenCL ");\r
875                         if (runOpenCLKernels)\r
876                                 printf("running the kernels");\r
877                         else\r
878                                 printf("without running the kernels");\r
879                         printf("\n");\r
880                 }\r
881         }\r
882 \r
883         glBindVertexArray(cube_vao);\r
884 \r
885         glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 9*sizeof(float), 0);\r
886         glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, (GLvoid *)(sizeof(cube_vertices)));\r
887         glVertexAttribPointer(2, 4, GL_FLOAT, GL_FALSE, 0, (GLvoid *)(sizeof(cube_vertices)+POSITION_BUFFER_SIZE));\r
888         int uvoffset = 7*sizeof(float);\r
889         int normaloffset = 4*sizeof(float);\r
890 \r
891         glVertexAttribPointer(3, 2, GL_FLOAT, GL_FALSE, 9*sizeof(float), (GLvoid *)uvoffset);\r
892         glVertexAttribPointer(4, 3, GL_FLOAT, GL_FALSE, 9*sizeof(float), (GLvoid *)normaloffset);\r
893 \r
894         glEnableVertexAttribArray(0);\r
895         glEnableVertexAttribArray(1);\r
896         glEnableVertexAttribArray(2);\r
897         glEnableVertexAttribArray(3);\r
898         glEnableVertexAttribArray(4);\r
899 \r
900         glVertexAttribDivisor(1, 1);\r
901         glVertexAttribDivisor(2, 1);\r
902         glVertexAttribDivisor(3, 0);\r
903         glVertexAttribDivisor(4, 0);\r
904 \r
905         glUseProgram(instancingShader);\r
906         glUniform1f(angle_loc, 0);\r
907         GLfloat pm[16];\r
908         glGetFloatv(GL_PROJECTION_MATRIX, pm);\r
909         glUniformMatrix4fv(ProjectionMatrix, 1, false, &pm[0]);\r
910 \r
911         GLfloat mvm[16];\r
912         glGetFloatv(GL_MODELVIEW_MATRIX, mvm);\r
913         glUniformMatrix4fv(ModelViewMatrix, 1, false, &mvm[0]);\r
914 \r
915         glUniform1i(uniform_texture_diffuse, 0);\r
916 \r
917         glFlush();\r
918         int numInstances = NUM_OBJECTS;\r
919         int indexCount = sizeof(cube_indices)/sizeof(int);\r
920         int indexOffset = 0;\r
921 \r
922         glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_vbo);\r
923         glDrawElementsInstanced(GL_TRIANGLES, indexCount, GL_UNSIGNED_INT, (void*)indexOffset, numInstances);\r
924 \r
925         glUseProgram(0);\r
926         glBindBuffer(GL_ARRAY_BUFFER,0);\r
927         glBindVertexArray(0);\r
928 \r
929         glutSwapBuffers();\r
930         glutPostRedisplay();\r
931 \r
932         GLint err = glGetError();\r
933         assert(err==GL_NO_ERROR);\r
934 }\r
935 \r
936 \r
937 void ChangeSize(int w, int h)\r
938 {\r
939         m_glutScreenWidth = w;\r
940         m_glutScreenHeight = h;\r
941 \r
942 #ifdef RECREATE_CL_AND_SHADERS_ON_RESIZE\r
943         delete g_interopBuffer;\r
944         clReleaseKernel(g_interopKernel);\r
945         DeleteCL();\r
946         DeleteShaders();\r
947 #endif //RECREATE_CL_AND_SHADERS_ON_RESIZE\r
948 \r
949         // Set Viewport to window dimensions\r
950         glViewport(0, 0, w, h);\r
951 \r
952 #ifdef RECREATE_CL_AND_SHADERS_ON_RESIZE\r
953         InitCL();\r
954         InitShaders();\r
955         \r
956         g_interopBuffer = new btOpenCLGLInteropBuffer(g_cxMainContext,g_cqCommandQue,cube_vbo);\r
957         clFinish(g_cqCommandQue);\r
958         g_interopKernel = btOpenCLUtils::compileCLKernelFromString(g_cxMainContext, interopKernelString, "interopKernel" );\r
959 #endif //RECREATE_CL_AND_SHADERS_ON_RESIZE\r
960 \r
961 }\r
962 \r
963 void Keyboard(unsigned char key, int x, int y)\r
964 {\r
965         switch (key)\r
966         {\r
967         case 27:\r
968                 done = true;\r
969                 break;\r
970         case 'O':\r
971         case 'o':\r
972                 {\r
973                         m_ortho = !m_ortho;\r
974                         break;\r
975                 }\r
976         case 'c':\r
977         case 'C':\r
978                 {\r
979                         useCPU = !useCPU;\r
980                         if (useCPU)\r
981                                 printf("using CPU\n");\r
982                         else\r
983                                 printf("using OpenCL\n");\r
984                         break;\r
985                 }\r
986         case 's':\r
987         case 'S':\r
988                 {\r
989                         printStats = !printStats;\r
990                         break;\r
991                 }\r
992         case 'k':\r
993         case 'K':\r
994                 {\r
995                         runOpenCLKernels=!runOpenCLKernels;\r
996                         break;\r
997                 }\r
998         case 'q':\r
999         case 'Q':\r
1000                 exit(0);\r
1001         default:\r
1002                 break;\r
1003         }\r
1004 }\r
1005 \r
1006 // Cleanup\r
1007 void ShutdownRC(void)\r
1008 {\r
1009         glDeleteBuffers(1, &cube_vbo);\r
1010         glDeleteVertexArrays(1, &cube_vao);\r
1011 }\r
1012 \r
1013 int main(int argc, char* argv[])\r
1014 {\r
1015         //      printf("vertexShader = \n%s\n",vertexShader);\r
1016         //      printf("fragmentShader = \n%s\n",fragmentShader);\r
1017 \r
1018         glutInit(&argc, argv);\r
1019 \r
1020         glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA);\r
1021 \r
1022 \r
1023         glutInitWindowSize(m_glutScreenWidth, m_glutScreenHeight);\r
1024         char buf[1024];\r
1025         sprintf(buf,"OpenCL - OpenGL interop, transforms %d cubes on the GPU (use c to toggle CPU/CL)", NUM_OBJECTS);\r
1026         glutCreateWindow(buf);\r
1027 \r
1028         glutReshapeFunc(ChangeSize);\r
1029 \r
1030         glutKeyboardFunc(Keyboard);\r
1031         glutDisplayFunc(RenderScene);\r
1032 \r
1033         GLenum err = glewInit();\r
1034         if (GLEW_OK != err)\r
1035         {\r
1036                 /* Problem: glewInit failed, something is seriously wrong. */\r
1037                 fprintf(stderr, "Error: %s\n", glewGetErrorString(err));\r
1038         }\r
1039 \r
1040         //ChangeSize(m_glutScreenWidth,m_glutScreenHeight);\r
1041 \r
1042         InitCL();\r
1043         \r
1044 \r
1045         InitShaders();\r
1046         \r
1047         g_interopBuffer = new btOpenCLGLInteropBuffer(g_cxMainContext,g_cqCommandQue,cube_vbo);\r
1048         clFinish(g_cqCommandQue);\r
1049 \r
1050 \r
1051         g_interopKernel = btOpenCLUtils::compileCLKernelFromString(g_cxMainContext, g_device,interopKernelString, "interopKernel" );\r
1052 \r
1053         glutMainLoop();\r
1054         ShutdownRC();\r
1055 \r
1056         return 0;\r
1057 }\r