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
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
10 //#define _USE_SUB_DATA
\r
12 //#define NUM_OBJECTS_X 100
\r
13 //#define NUM_OBJECTS_Y 100
\r
14 //#define NUM_OBJECTS_Z 100
\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
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
25 #include <GL/glew.h>
\r
28 #include "btGlutInclude.h"
\r
29 #include "btStopwatch.h"
\r
32 #include "btVector3.h"
\r
33 #include "btQuaternion.h"
\r
34 #include "btMatrix3x3.h"
\r
35 static float angle(0);
\r
40 #include <windows.h>
\r
44 #include "../basic_initialize/btOpenCLUtils.h"
\r
45 #include "btOpenCLGLInteropBuffer.h"
\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
53 btOpenCLGLInteropBuffer* g_interopBuffer = 0;
\r
54 cl_kernel g_interopKernel;
\r
56 bool useCPU = false;
\r
57 bool printStats = false;
\r
58 bool runOpenCLKernels = true;
\r
60 #define MSTRINGIFY(A) #A
\r
61 static char* interopKernelString =
\r
62 #include "interopKernel.cl"
\r
64 btStopwatch gStopwatch;
\r
65 int m_glutScreenWidth = 640;
\r
66 int m_glutScreenHeight= 480;
\r
68 bool m_ortho = false;
\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
76 static bool done = false;
\r
77 static GLint angle_loc = 0;
\r
78 static GLint ModelViewMatrix;
\r
79 static GLint ProjectionMatrix;
\r
82 static GLint uniform_texture_diffuse = 0;
\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
88 static const char* vertexShader= \
\r
90 "precision highp float;\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
101 "uniform float angle = 0.0;\n"
\r
102 "uniform mat4 ModelViewMatrix;\n"
\r
103 "uniform mat4 ProjectionMatrix;\n"
\r
112 " vec2 texcoord;\n"
\r
116 "vec4 quatMul ( in vec4 q1, in vec4 q2 )\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
124 "vec4 quatFromAxisAngle(vec4 axis, in float angle)\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
133 "// vector rotation via quaternion\n"
\r
135 "vec4 quatRotate3 ( in vec3 p, in vec4 q )\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
140 "vec4 quatRotate ( in vec4 p, in vec4 q )\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
146 "out vec3 lightDir,normal,ambient;\n"
\r
148 "void main(void)\n"
\r
150 " vec4 q = instance_quaternion;\n"
\r
151 " ambient = vec3(0.2,0.2,0.2);\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
158 " lightDir = normalize(light_pos);//gl_LightSource[0].position.xyz));\n"
\r
159 "// lightDir = normalize(vec3(gl_LightSource[0].position));\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
165 " gl_Position = vertexPos;\n"
\r
167 "// fragment.color = instance_color;\n"
\r
168 " vert.texcoord = uvcoords;\n"
\r
173 static const char* fragmentShader= \
\r
175 "precision highp float;\n"
\r
184 " vec2 texcoord;\n"
\r
187 "uniform sampler2D Diffuse;\n"
\r
189 "in vec3 lightDir,normal,ambient;\n"
\r
191 "out vec4 color;\n"
\r
193 "void main_textured(void)\n"
\r
195 " color = texture2D(Diffuse,vert.texcoord);//fragment.color;\n"
\r
198 "void main(void)\n"
\r
200 " vec4 texel = texture2D(Diffuse,vert.texcoord);//fragment.color;\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
207 " ct = texel.rgb;\n"
\r
210 " color = vec4(ct * cf, at * af); \n"
\r
215 // Load the shader from the source text
\r
216 void gltLoadShaderSrc(const char *szShaderSrc, GLuint shader)
\r
218 GLchar *fsStringPtr[1];
\r
220 fsStringPtr[0] = (GLchar *)szShaderSrc;
\r
221 glShaderSource(shader, 1, (const GLchar **)fsStringPtr, NULL);
\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
230 GLint shaderLength = 0;
\r
233 // Open the shader file
\r
234 fp = fopen(szFile, "r");
\r
237 // See how long the file is
\r
238 while (fgetc(fp) != EOF)
\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
249 // Go back to beginning of file
\r
252 // Read the whole file in
\r
253 if (shaderText != NULL)
\r
254 fread(shaderText, 1, shaderLength, fp);
\r
256 // Make sure it is null terminated and close the file
\r
257 shaderText[shaderLength] = '\0';
\r
263 // printf(shaderText);
\r
265 gltLoadShaderSrc((const char *)shaderText, shader);
\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
277 // Temporary Shader objects
\r
278 GLuint hVertexShader;
\r
279 GLuint hFragmentShader;
\r
280 GLuint hReturn = 0;
\r
283 // Create shader objects
\r
284 hVertexShader = glCreateShader(GL_VERTEX_SHADER);
\r
285 hFragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
\r
290 if(gltLoadShaderFile(szVertexProg, hVertexShader) == false)
\r
292 glDeleteShader(hVertexShader);
\r
293 glDeleteShader(hFragmentShader);
\r
294 return (GLuint)NULL;
\r
297 if(gltLoadShaderFile(szFragmentProg, hFragmentShader) == false)
\r
299 glDeleteShader(hVertexShader);
\r
300 glDeleteShader(hFragmentShader);
\r
301 return (GLuint)NULL;
\r
305 gltLoadShaderSrc(vertexShader, hVertexShader);
\r
306 gltLoadShaderSrc(fragmentShader, hFragmentShader);
\r
309 glCompileShader(hVertexShader);
\r
310 glCompileShader(hFragmentShader);
\r
312 // Check for errors
\r
313 glGetShaderiv(hVertexShader, GL_COMPILE_STATUS, &testVal);
\r
314 if(testVal == GL_FALSE)
\r
316 char temp[256] = "";
\r
317 glGetShaderInfoLog( hVertexShader, 256, NULL, temp);
\r
318 fprintf( stderr, "Compile failed:\n%s\n", temp);
\r
321 glDeleteShader(hVertexShader);
\r
322 glDeleteShader(hFragmentShader);
\r
323 return (GLuint)NULL;
\r
326 glGetShaderiv(hFragmentShader, GL_COMPILE_STATUS, &testVal);
\r
327 if(testVal == GL_FALSE)
\r
329 char temp[256] = "";
\r
330 glGetShaderInfoLog( hFragmentShader, 256, NULL, temp);
\r
331 fprintf( stderr, "Compile failed:\n%s\n", temp);
\r
334 glDeleteShader(hVertexShader);
\r
335 glDeleteShader(hFragmentShader);
\r
336 return (GLuint)NULL;
\r
339 // Link them - assuming it works...
\r
340 hReturn = glCreateProgram();
\r
341 glAttachShader(hReturn, hVertexShader);
\r
342 glAttachShader(hReturn, hFragmentShader);
\r
344 glLinkProgram(hReturn);
\r
346 // These are no longer needed
\r
347 glDeleteShader(hVertexShader);
\r
348 glDeleteShader(hFragmentShader);
\r
350 // Make sure link worked too
\r
351 glGetProgramiv(hReturn, GL_LINK_STATUS, &testVal);
\r
352 if(testVal == GL_FALSE)
\r
354 glDeleteProgram(hReturn);
\r
355 return (GLuint)NULL;
\r
361 ///position xyz, unused w, normal, uv
\r
362 static const GLfloat cube_vertices[] =
\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
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
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
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
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
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
395 static const int cube_indices[]=
\r
397 0,1,2,0,2,3,//ground face
\r
398 4,5,6,4,6,7,//top face
\r
411 clReleaseContext(g_cxMainContext);
\r
412 clReleaseCommandQueue(g_cqCommandQue);
\r
421 glCtx = wglGetCurrentContext();
\r
423 GLXContext glCtx = glXGetCurrentContext();
\r
425 glDC = wglGetCurrentDC();
\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
432 int numDev = btOpenCLUtils::getNumDevices(g_cxMainContext);
\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
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
455 GLfloat* instance_positions_ptr = 0;
\r
456 GLfloat* instance_quaternion_ptr = 0;
\r
458 void DeleteShaders()
\r
460 glDeleteVertexArrays(1, &cube_vao);
\r
461 glDeleteBuffers(1,&index_vbo);
\r
462 glDeleteBuffers(1,&cube_vbo);
\r
463 glDeleteProgram(instancingShader);
\r
466 void writeTransforms()
\r
471 char* bla = (char*)glMapBuffer( GL_ARRAY_BUFFER,GL_READ_WRITE);//GL_WRITE_ONLY
\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
477 static int offset=0;
\r
480 static btVector3 axis(1,0,0);
\r
483 btQuaternion orn(axis,angle);
\r
484 for (int i=0;i<NUM_OBJECTS_X;i++)
\r
486 for (int j=0;j<NUM_OBJECTS_Y;j++)
\r
488 for (int k=0;k<NUM_OBJECTS_Z;k++)
\r
490 //if (!((index+offset)%15))
\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
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
503 // memcpy((void*)&orientations[index*4],orn,sizeof(btQuaternion));
\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
517 bool loadFromFile = false;
\r
518 instancingShader = gltLoadShaderPair("instancing.vs","instancing.fs", loadFromFile);
\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
530 glGenBuffers(1, &cube_vbo);
\r
531 glBindBuffer(GL_ARRAY_BUFFER, cube_vbo);
\r
533 instance_positions_ptr = (GLfloat*)new float[NUM_OBJECTS*4];
\r
534 instance_quaternion_ptr = (GLfloat*)new float[NUM_OBJECTS*4];
\r
536 for (int i=0;i<NUM_OBJECTS_X;i++)
\r
538 for (int j=0;j<NUM_OBJECTS_Y;j++)
\r
540 for (int k=0;k<NUM_OBJECTS_Z;k++)
\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
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
556 int size = sizeof(cube_vertices) + POSITION_BUFFER_SIZE+ORIENTATION_BUFFER_SIZE;
\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
564 glBufferData(GL_ARRAY_BUFFER, size, bla, GL_DYNAMIC_DRAW);//GL_STATIC_DRAW);
\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
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
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
585 glGenVertexArrays(1, &cube_vao);
\r
586 glBindVertexArray(cube_vao);
\r
587 glBindBuffer(GL_ARRAY_BUFFER, cube_vbo);
\r
588 glBindVertexArray(0);
\r
590 glGenBuffers(1, &index_vbo);
\r
591 int indexBufferSize = sizeof(cube_indices);
\r
592 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_vbo);
\r
594 glBufferData(GL_ELEMENT_ARRAY_BUFFER, indexBufferSize, NULL, GL_STATIC_DRAW);
\r
595 glBufferSubData(GL_ELEMENT_ARRAY_BUFFER,0,indexBufferSize,cube_indices);
\r
597 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
\r
598 glBindBuffer(GL_ARRAY_BUFFER,0);
\r
599 glBindVertexArray(0);
\r
605 void updateCamera() {
\r
610 btVector3 m_cameraPosition(12,20,12);
\r
611 btVector3 m_cameraTargetPosition(0,10,0);
\r
613 btVector3 m_cameraUp(0,1,0);
\r
614 int m_forwardAxis=2;
\r
615 btScalar m_cameraDistance = 130;
\r
617 glMatrixMode(GL_PROJECTION);
\r
621 float m_frustumZNear=1;
\r
622 float m_frustumZFar=1000;
\r
624 if (m_glutScreenWidth == 0 && m_glutScreenHeight == 0)
\r
630 if (m_glutScreenWidth > m_glutScreenHeight)
\r
632 aspect = m_glutScreenWidth / (float)m_glutScreenHeight;
\r
633 extents.setValue(aspect * 1.0f, 1.0f,0);
\r
636 aspect = m_glutScreenHeight / (float)m_glutScreenWidth;
\r
637 extents.setValue(1.0f, aspect*1.f,0);
\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
650 glMatrixMode(GL_MODELVIEW);
\r
654 if (m_glutScreenWidth > m_glutScreenHeight)
\r
656 glFrustum (-aspect * m_frustumZNear, aspect * m_frustumZNear, -m_frustumZNear, m_frustumZNear, m_frustumZNear, m_frustumZFar);
\r
659 glFrustum (-aspect * m_frustumZNear, aspect * m_frustumZNear, -m_frustumZNear, m_frustumZNear, m_frustumZNear, m_frustumZFar);
\r
661 glMatrixMode(GL_MODELVIEW);
\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
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
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
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
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
695 glEnable(GL_LIGHTING);
\r
696 glEnable(GL_LIGHT0);
\r
697 glEnable(GL_LIGHT1);
\r
700 // glShadeModel(GL_FLAT);//GL_SMOOTH);
\r
701 glShadeModel(GL_SMOOTH);
\r
703 glEnable(GL_DEPTH_TEST);
\r
704 glDepthFunc(GL_LESS);
\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
711 static bool m_textureenabled = true;
\r
712 static bool m_textureinitialized = false;
\r
715 if(m_textureenabled)
\r
717 if(!m_textureinitialized)
\r
719 glActiveTexture(GL_TEXTURE0);
\r
721 GLubyte* image=new GLubyte[256*256*3];
\r
722 for(int y=0;y<256;++y)
\r
725 GLubyte* pi=image+y*256*3;
\r
726 for(int x=0;x<256;++x)
\r
729 const GLubyte b=180;
\r
730 GLubyte c=b+((s+t&1)&1)*(255-b);
\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
747 m_textureinitialized=true;
\r
749 // glMatrixMode(GL_TEXTURE);
\r
750 // glLoadIdentity();
\r
751 // glMatrixMode(GL_MODELVIEW);
\r
753 glEnable(GL_TEXTURE_2D);
\r
754 glBindTexture(GL_TEXTURE_2D,m_texturehandle);
\r
758 glDisable(GL_TEXTURE_2D);
\r
761 glEnable(GL_COLOR_MATERIAL);
\r
764 // glEnable(GL_CULL_FACE);
\r
765 // glCullFace(GL_BACK);
\r
768 //#pragma optimize( "g", off )
\r
777 for (int i=0;i<NUM_OBJECTS_X;i++)
\r
779 for (int j=0;j<NUM_OBJECTS_Y;j++)
\r
781 for (int k=0;k<NUM_OBJECTS_Z;k++)
\r
783 //if (!((index+offset)%15))
\r
785 instance_positions_ptr[index*4+1]-=0.01f;
\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
803 int numObjects = NUM_OBJECTS;
\r
804 int offset = (sizeof(cube_vertices) )/4;
\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
813 ciErrNum = clEnqueueReleaseGLObjects(g_cqCommandQue, 1, &clBuffer, 0, 0, 0);
\r
814 oclCHECKERROR(ciErrNum, CL_SUCCESS);
\r
815 clFinish(g_cqCommandQue);
\r
820 //#pragma optimize( "g", on )
\r
822 void RenderScene(void)
\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
837 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
\r
839 //render coordinate system
\r
852 //do a finish, to make sure timings are clean
\r
855 float start = gStopwatch.getTimeMilliseconds();
\r
857 // glBindBuffer(GL_ARRAY_BUFFER, 0);
\r
858 glBindBuffer(GL_ARRAY_BUFFER, cube_vbo);
\r
862 float stop = gStopwatch.getTimeMilliseconds();
\r
863 gStopwatch.reset();
\r
867 printf("updatePos=%f ms on ",stop-start);
\r
875 if (runOpenCLKernels)
\r
876 printf("running the kernels");
\r
878 printf("without running the kernels");
\r
883 glBindVertexArray(cube_vao);
\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
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
894 glEnableVertexAttribArray(0);
\r
895 glEnableVertexAttribArray(1);
\r
896 glEnableVertexAttribArray(2);
\r
897 glEnableVertexAttribArray(3);
\r
898 glEnableVertexAttribArray(4);
\r
900 glVertexAttribDivisor(1, 1);
\r
901 glVertexAttribDivisor(2, 1);
\r
902 glVertexAttribDivisor(3, 0);
\r
903 glVertexAttribDivisor(4, 0);
\r
905 glUseProgram(instancingShader);
\r
906 glUniform1f(angle_loc, 0);
\r
908 glGetFloatv(GL_PROJECTION_MATRIX, pm);
\r
909 glUniformMatrix4fv(ProjectionMatrix, 1, false, &pm[0]);
\r
912 glGetFloatv(GL_MODELVIEW_MATRIX, mvm);
\r
913 glUniformMatrix4fv(ModelViewMatrix, 1, false, &mvm[0]);
\r
915 glUniform1i(uniform_texture_diffuse, 0);
\r
918 int numInstances = NUM_OBJECTS;
\r
919 int indexCount = sizeof(cube_indices)/sizeof(int);
\r
920 int indexOffset = 0;
\r
922 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_vbo);
\r
923 glDrawElementsInstanced(GL_TRIANGLES, indexCount, GL_UNSIGNED_INT, (void*)indexOffset, numInstances);
\r
926 glBindBuffer(GL_ARRAY_BUFFER,0);
\r
927 glBindVertexArray(0);
\r
930 glutPostRedisplay();
\r
932 GLint err = glGetError();
\r
933 assert(err==GL_NO_ERROR);
\r
937 void ChangeSize(int w, int h)
\r
939 m_glutScreenWidth = w;
\r
940 m_glutScreenHeight = h;
\r
942 #ifdef RECREATE_CL_AND_SHADERS_ON_RESIZE
\r
943 delete g_interopBuffer;
\r
944 clReleaseKernel(g_interopKernel);
\r
947 #endif //RECREATE_CL_AND_SHADERS_ON_RESIZE
\r
949 // Set Viewport to window dimensions
\r
950 glViewport(0, 0, w, h);
\r
952 #ifdef RECREATE_CL_AND_SHADERS_ON_RESIZE
\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
963 void Keyboard(unsigned char key, int x, int y)
\r
973 m_ortho = !m_ortho;
\r
981 printf("using CPU\n");
\r
983 printf("using OpenCL\n");
\r
989 printStats = !printStats;
\r
995 runOpenCLKernels=!runOpenCLKernels;
\r
1007 void ShutdownRC(void)
\r
1009 glDeleteBuffers(1, &cube_vbo);
\r
1010 glDeleteVertexArrays(1, &cube_vao);
\r
1013 int main(int argc, char* argv[])
\r
1015 // printf("vertexShader = \n%s\n",vertexShader);
\r
1016 // printf("fragmentShader = \n%s\n",fragmentShader);
\r
1018 glutInit(&argc, argv);
\r
1020 glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA);
\r
1023 glutInitWindowSize(m_glutScreenWidth, m_glutScreenHeight);
\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
1028 glutReshapeFunc(ChangeSize);
\r
1030 glutKeyboardFunc(Keyboard);
\r
1031 glutDisplayFunc(RenderScene);
\r
1033 GLenum err = glewInit();
\r
1034 if (GLEW_OK != err)
\r
1036 /* Problem: glewInit failed, something is seriously wrong. */
\r
1037 fprintf(stderr, "Error: %s\n", glewGetErrorString(err));
\r
1040 //ChangeSize(m_glutScreenWidth,m_glutScreenHeight);
\r
1047 g_interopBuffer = new btOpenCLGLInteropBuffer(g_cxMainContext,g_cqCommandQue,cube_vbo);
\r
1048 clFinish(g_cqCommandQue);
\r
1051 g_interopKernel = btOpenCLUtils::compileCLKernelFromString(g_cxMainContext, g_device,interopKernelString, "interopKernel" );
\r