Advertisement
Guest User

OpenGL-OpenCl code

a guest
May 29th, 2015
210
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 28.18 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <math.h>
  3. #include <string.h>
  4. #include <stdlib.h>
  5. #include <ctype.h>
  6. #include <omp.h>
  7.  
  8. #define _USE_MATH_DEFINES
  9. #include <math.h>
  10.  
  11. #ifdef WIN32
  12. #include <windows.h>
  13. #pragma warning(disable:4996)
  14. #endif
  15.  
  16. #ifdef WIN32
  17. #include "glew.h"
  18. #endif
  19.  
  20. #include <OpenGL/gl.h>
  21. #include <OpenGL/glu.h>
  22. #include "GLUT/glut.h"
  23. #include "GLUI/glui.h"
  24.  
  25. #include "CL/cl.h"
  26. #include "CL/cl_gl.h"
  27.  
  28.  
  29. // title of these windows:
  30.  
  31. const char *WINDOWTITLE = { "OpenCL/OpenGL Particle System -- Joe Parallel" };
  32. const char *GLUITITLE   = { "User Interface Window" };
  33.  
  34. // random parameters:                  
  35.  
  36. const float XMIN =  { -100.0 };
  37. const float XMAX =  {  100.0 };
  38. const float YMIN =  { -100.0 };
  39. const float YMAX =  {  100.0 };
  40. const float ZMIN =  { -100.0 };
  41. const float ZMAX =  {  100.0 };
  42.  
  43. const float VMIN =  {   -100. };
  44. const float VMAX =  {    100. };
  45.  
  46.  
  47. const int NUM_PARTICLES = 1024*1024;
  48. const int LOCAL_SIZE    = 32;
  49. const char *CL_FILE_NAME   = { "particles.cl" };
  50. const char *CL_BINARY_NAME = { "particles.nv" };
  51.  
  52.  
  53. const int GLUITRUE  = { true  };
  54. const int GLUIFALSE = { false };
  55.  
  56. #define ESCAPE      0x1b
  57.  
  58. const int INIT_WINDOW_SIZE = { 700 };       // window size in pixels
  59.  
  60. const float ANGFACT = { 1. };
  61. const float SCLFACT = { 0.005f };
  62. const float MINSCALE = { 0.001f };
  63.  
  64. const int LEFT   = { 4 };
  65. const int MIDDLE = { 2 };
  66. const int RIGHT  = { 1 };
  67.  
  68. enum Projections
  69. {
  70.     ORTHO,
  71.     PERSP
  72. };
  73.  
  74. enum ButtonVals
  75. {
  76.     GO,
  77.     PAUSE,
  78.     RESET,
  79.     QUIT
  80. };
  81.  
  82. const float BACKCOLOR[ ] = { 0., 0., 0., 0. };
  83.  
  84. const GLfloat AXES_COLOR[ ] = { 1., .5, 0. };
  85. const GLfloat AXES_WIDTH   = { 3. };
  86.  
  87. //
  88. // structs we will need later:
  89.  
  90. struct xyzw
  91. {
  92.     float x, y, z, w;
  93. };
  94.  
  95. struct rgba
  96. {
  97.     float r, g, b, a;
  98. };
  99.  
  100.  
  101. // non-constant global variables:
  102.  
  103. int ActiveButton;       // current button that is down
  104. GLuint  AxesList;       // list to hold the axes
  105. int AxesOn;         // ON or OFF
  106. GLUI *  Glui;           // instance of glui window
  107. int GluiWindow;     // the glut id for the glui window
  108. int MainWindow;     // window id for main graphics window
  109. int Paused;
  110. GLfloat RotMatrix[4][4];    // set by glui rotation widget
  111. float   Scale, Scale2;      // scaling factors
  112. GLuint  SphereList;
  113. int WhichProjection;    // ORTHO or PERSP
  114. int Xmouse, Ymouse;     // mouse values
  115. float   Xrot, Yrot;     // rotation angles in degrees
  116. float   TransXYZ[3];        // set by glui translation widgets
  117.  
  118. double  ElapsedTime;
  119. int     ShowPerformance;
  120.  
  121. size_t GlobalWorkSize[3] = { NUM_PARTICLES, 1, 1 };
  122. size_t LocalWorkSize[3]  = { LOCAL_SIZE,    1, 1 };
  123.  
  124. GLuint          hPobj;
  125. GLuint          hCobj;
  126. cl_mem          dPobj;
  127. cl_mem          dCobj;
  128. struct xyzw *   hVel;
  129. cl_mem          dVel;
  130. cl_command_queue    CmdQueue;
  131. cl_device_id        Device;
  132. cl_kernel       Kernel;
  133. cl_platform_id      Platform;
  134. cl_program      Program;
  135. cl_platform_id      PlatformID;
  136.  
  137.  
  138.  
  139.  
  140.  
  141.  
  142. //
  143. // function prototypes:
  144. //
  145.  
  146. inline
  147. float
  148. SQR( float x )
  149. {
  150.     return x * x;
  151. }
  152.  
  153. void    Animate( );
  154. void    Axes( float );
  155. void    Buttons( int );
  156. void    Display( );
  157. void    DoRasterString( float, float, float, char * );
  158. void    DoStrokeString( float, float, float, float, char * );
  159. void    InitCL( );
  160. void    InitGlui( );
  161. void    InitGraphics( );
  162. void    InitLists( );
  163. bool    IsCLExtensionSupported( const char * );
  164. void    Keyboard( unsigned char, int, int );
  165. void    MouseButton( int, int, int, int );
  166. void    MouseMotion( int, int );
  167. void    PrintCLError( cl_int, char * = "", FILE * = stderr );
  168. void    Quit( );
  169. float   Ranf( float, float );
  170. void    Reset( );
  171. void    ResetParticles( );
  172. void    Resize( int, int );
  173. void    Traces( int );
  174. void    Visibility( int );
  175.  
  176.  
  177. //
  178. // main Program:
  179. //
  180.  
  181. int
  182. main( int argc, char *argv[ ] )
  183. {
  184.     glutInit( &argc, argv );
  185.     InitGraphics( );
  186.     InitLists( );
  187.     InitCL( );
  188.     Reset( );
  189.     InitGlui( );
  190.     glutMainLoop( );
  191.     return 0;
  192. }
  193.  
  194. void
  195. Animate( )
  196. {
  197.     cl_int  status;
  198.     double time0, time1;
  199.  
  200.     // acquire the vertex buffers from opengl:
  201.  
  202.     glutSetWindow( MainWindow );
  203.     glFinish( );
  204.  
  205.     status = clEnqueueAcquireGLObjects( CmdQueue, 1, &dPobj, 0, NULL, NULL );
  206.     PrintCLError( status, "clEnqueueAcquireGLObjects (1): " );
  207.     status = clEnqueueAcquireGLObjects( CmdQueue, 1, &dCobj, 0, NULL, NULL );
  208.     PrintCLError( status, "clEnqueueAcquireGLObjects (2): " );
  209.  
  210.     if( ShowPerformance )
  211.         time0 = omp_get_wtime( );
  212.  
  213.     // 11. enqueue the Kernel object for execution:
  214.  
  215.     cl_event wait;
  216.     status = clEnqueueNDRangeKernel( CmdQueue, Kernel, 1, NULL, GlobalWorkSize, LocalWorkSize, 0, NULL, &wait );
  217.     PrintCLError( status, "clEnqueueNDRangeKernel: " );
  218.  
  219.     if( ShowPerformance )
  220.     {
  221.         status = clWaitForEvents( 1, &wait );
  222.         PrintCLError( status, "clWaitForEvents: " );
  223.         time1 = omp_get_wtime( );
  224.         ElapsedTime = time1 - time0;
  225.     }
  226.  
  227.     clFinish( CmdQueue );
  228.     status = clEnqueueReleaseGLObjects( CmdQueue, 1, &dCobj, 0, NULL, NULL );
  229.     PrintCLError( status, "clEnqueueReleaseGLObjects (2): " );
  230.     status = clEnqueueReleaseGLObjects( CmdQueue, 1, &dPobj, 0, NULL, NULL );
  231.     PrintCLError( status, "clEnqueueReleaseGLObjects (2): " );
  232.  
  233.     glutSetWindow( MainWindow );
  234.     glutPostRedisplay( );
  235. }
  236.  
  237.  
  238.  
  239.  
  240. //
  241. // glui buttons callback:
  242. //
  243.  
  244. void
  245. Buttons( int id )
  246. {
  247.     cl_int status;
  248.     switch( id )
  249.     {
  250.         case GO:
  251.             GLUI_Master.set_glutIdleFunc( Animate );
  252.             break;
  253.  
  254.         case PAUSE:
  255.             Paused = ! Paused;
  256.             if( Paused )
  257.                 GLUI_Master.set_glutIdleFunc( NULL );
  258.             else
  259.                 GLUI_Master.set_glutIdleFunc( Animate );
  260.             break;
  261.  
  262.         case RESET:
  263.             Reset( );
  264.             ResetParticles( );
  265.             status = clEnqueueWriteBuffer( CmdQueue, dVel, CL_FALSE, 0, 4*sizeof(float)*NUM_PARTICLES, hVel, 0, NULL, NULL );
  266.             PrintCLError( status, "clEneueueWriteBuffer: " );
  267.             GLUI_Master.set_glutIdleFunc( NULL );
  268.             Glui->sync_live( );
  269.             glutSetWindow( MainWindow );
  270.             glutPostRedisplay( );
  271.             break;
  272.  
  273.         case QUIT:
  274.             Quit( );
  275.             break;
  276.  
  277.         default:
  278.             fprintf( stderr, "Don't know what to do with Button ID %d\n", id );
  279.     }
  280.  
  281. }
  282.  
  283.  
  284.  
  285. //
  286. // draw the complete scene:
  287. //
  288.  
  289. void
  290. Display( )
  291. {
  292.     glutSetWindow( MainWindow );
  293.     glDrawBuffer( GL_BACK );
  294.     glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
  295.     glEnable( GL_DEPTH_TEST );
  296.     glShadeModel( GL_FLAT );
  297.     GLsizei vx = glutGet( GLUT_WINDOW_WIDTH );
  298.     GLsizei vy = glutGet( GLUT_WINDOW_HEIGHT );
  299.     GLsizei v = vx < vy ? vx : vy;          // minimum dimension
  300.     GLint xl = ( vx - v ) / 2;
  301.     GLint yb = ( vy - v ) / 2;
  302.     glViewport( xl, yb,  v, v );
  303.  
  304.  
  305.     glMatrixMode( GL_PROJECTION );
  306.     glLoadIdentity( );
  307.     if( WhichProjection == ORTHO )
  308.         glOrtho( -300., 300.,  -300., 300., 0.1, 2000. );
  309.     else
  310.         gluPerspective( 50., 1.,    0.1, 2000. );
  311.  
  312.     glMatrixMode( GL_MODELVIEW );
  313.     glLoadIdentity( );
  314.     gluLookAt( 0., -100., 800.,     0., -100., 0.,     0., 1., 0. );
  315.     glTranslatef( (GLfloat)TransXYZ[0], (GLfloat)TransXYZ[1], -(GLfloat)TransXYZ[2] );
  316.     glRotatef( (GLfloat)Yrot, 0., 1., 0. );
  317.     glRotatef( (GLfloat)Xrot, 1., 0., 0. );
  318.     glMultMatrixf( (const GLfloat *) RotMatrix );
  319.     glScalef( (GLfloat)Scale, (GLfloat)Scale, (GLfloat)Scale );
  320.     float scale2 = 1. + Scale2;     // because glui translation starts at 0.
  321.     if( scale2 < MINSCALE )
  322.         scale2 = MINSCALE;
  323.     glScalef( (GLfloat)scale2, (GLfloat)scale2, (GLfloat)scale2 );
  324.  
  325.     glDisable( GL_FOG );
  326.  
  327.     if( AxesOn != GLUIFALSE )
  328.         glCallList( AxesList );
  329.  
  330.     // ****************************************
  331.     // Here is where you draw the current state of the particles:
  332.     // ****************************************
  333.  
  334.     glBindBuffer( GL_ARRAY_BUFFER, hPobj );
  335.     glVertexPointer( 4, GL_FLOAT, 0, (void *)0 );
  336.     glEnableClientState( GL_VERTEX_ARRAY );
  337.  
  338.     glBindBuffer( GL_ARRAY_BUFFER, hCobj );
  339.     glColorPointer( 4, GL_FLOAT, 0, (void *)0 );
  340.     glEnableClientState( GL_COLOR_ARRAY );
  341.  
  342.     glPointSize( 3. );
  343.     glDrawArrays( GL_POINTS, 0, NUM_PARTICLES );
  344.     glPointSize( 1. );
  345.  
  346.     glDisableClientState( GL_VERTEX_ARRAY );
  347.     glDisableClientState( GL_COLOR_ARRAY );
  348.     glBindBuffer( GL_ARRAY_BUFFER, 0 );
  349.  
  350.     glCallList( SphereList );
  351.  
  352.     if( ShowPerformance )
  353.     {
  354.         char str[128];
  355.         sprintf( str, "%6.1f GigaParticles/Sec", (float)NUM_PARTICLES/ElapsedTime/1000000000. );
  356.         glDisable( GL_DEPTH_TEST );
  357.         glMatrixMode( GL_PROJECTION );
  358.         glLoadIdentity();
  359.         gluOrtho2D( 0., 100.,     0., 100. );
  360.         glMatrixMode( GL_MODELVIEW );
  361.         glLoadIdentity();
  362.         glColor3f( 1., 1., 1. );
  363.         DoRasterString( 5., 95., 0., str );
  364.     }
  365.  
  366.     glutSwapBuffers( );
  367.     glFlush( );
  368. }
  369.  
  370.  
  371.  
  372. //
  373. // use glut to display a string of characters using a raster font:
  374. //
  375.  
  376. void
  377. DoRasterString( float x, float y, float z, char *s )
  378. {
  379.     char c;         // one character to print
  380.  
  381.     glRasterPos3f( (GLfloat)x, (GLfloat)y, (GLfloat)z );
  382.     for( ; ( c = *s ) != '\0'; s++ )
  383.     {
  384.         glutBitmapCharacter( GLUT_BITMAP_TIMES_ROMAN_24, c );
  385.     }
  386. }
  387.  
  388.  
  389.  
  390. //
  391. // use glut to display a string of characters using a stroke font:
  392. //
  393.  
  394. void
  395. DoStrokeString( float x, float y, float z, float ht, char *s )
  396. {
  397.     char c;         // one character to print
  398.  
  399.     glPushMatrix( );
  400.         glTranslatef( (GLfloat)x, (GLfloat)y, (GLfloat)z );
  401.         float sf = ht / ( 119.05 + 33.33 );
  402.         glScalef( (GLfloat)sf, (GLfloat)sf, (GLfloat)sf );
  403.         for( ; ( c = *s ) != '\0'; s++ )
  404.         {
  405.             glutStrokeCharacter( GLUT_STROKE_ROMAN, c );
  406.         }
  407.     glPopMatrix( );
  408. }
  409.  
  410.  
  411. //
  412. // initialize the opencl stuff:
  413. //
  414.  
  415. void
  416. InitCL( )
  417. {
  418.     // see if we can even open the opencl Kernel Program
  419.     // (no point going on if we can't):
  420.  
  421.     FILE *fp = fopen( CL_FILE_NAME, "r" );
  422.     if( fp == NULL )
  423.     {
  424.         fprintf( stderr, "Cannot open OpenCL source file '%s'\n", CL_FILE_NAME );
  425.         return;
  426.     }
  427.  
  428.     // 2. allocate the host memory buffers:
  429.  
  430.     cl_int status;      // returned status from opencl calls
  431.                 // test against CL_SUCCESS
  432.  
  433.     // get the platform id:
  434.  
  435.     status = clGetPlatformIDs( 1, &Platform, NULL );
  436.     PrintCLError( status, "clGetPlatformIDs: " );
  437.    
  438.     // get the device id:
  439.  
  440.     status = clGetDeviceIDs( Platform, CL_DEVICE_TYPE_GPU, 1, &Device, NULL );
  441.     PrintCLError( status, "clGetDeviceIDs: " );
  442.  
  443.  
  444.     // since this is an opengl interoperability program,
  445.     // check if the opengl sharing extension is supported,
  446.     // (no point going on if it isn't):
  447.     // (we need the Device in order to ask, so can't do it any sooner than here)
  448.  
  449.     if(  IsCLExtensionSupported( "cl_khr_gl_sharing" )  )
  450.     {
  451.         fprintf( stderr, "cl_khr_gl_sharing is supported.\n" );
  452.     }
  453.     else
  454.     {
  455.         fprintf( stderr, "cl_khr_gl_sharing is not supported -- sorry.\n" );
  456.         return;
  457.     }
  458.  
  459.  
  460.  
  461.     // 3. create an opencl context based on the opengl context:
  462.  
  463.     cl_context_properties props[ ] =
  464.     {
  465.         CL_GL_CONTEXT_KHR,      (cl_context_properties) wglGetCurrentContext( ),
  466.         CL_WGL_HDC_KHR,         (cl_context_properties) wglGetCurrentDC( ),
  467.         CL_CONTEXT_PLATFORM,        (cl_context_properties) Platform,
  468.         0
  469.     };
  470.  
  471.     cl_context Context = clCreateContext( props, 1, &Device, NULL, NULL, &status );
  472.     PrintCLError( status, "clCreateContext: " );
  473.  
  474.     // 4. create an opencl command queue:
  475.  
  476.     CmdQueue = clCreateCommandQueue( Context, Device, 0, &status );
  477.     if( status != CL_SUCCESS )
  478.         fprintf( stderr, "clCreateCommandQueue failed\n" );
  479.  
  480.     // create the velocity array and the opengl vertex array buffer and color array buffer:
  481.    
  482.     delete [ ] hVel;
  483.     hVel = new struct xyzw [ NUM_PARTICLES ];
  484.  
  485.     glGenBuffers( 1, &hPobj );
  486.     glBindBuffer( GL_ARRAY_BUFFER, hPobj );
  487.     glBufferData( GL_ARRAY_BUFFER, 4 * NUM_PARTICLES * sizeof(float), NULL, GL_STATIC_DRAW );
  488.  
  489.     glGenBuffers( 1, &hCobj );
  490.     glBindBuffer( GL_ARRAY_BUFFER, hCobj );
  491.     glBufferData( GL_ARRAY_BUFFER, 4 * NUM_PARTICLES * sizeof(float), NULL, GL_STATIC_DRAW );
  492.  
  493.     glBindBuffer( GL_ARRAY_BUFFER, 0 ); // unbind the buffer
  494.  
  495.     // fill those arrays and buffers:
  496.  
  497.     ResetParticles( );
  498.  
  499.     // 5. create the opencl version of the opengl buffers:
  500.  
  501.     dPobj = clCreateFromGLBuffer( Context, 0, hPobj, &status );
  502.     PrintCLError( status, "clCreateFromGLBuffer (1)" );
  503.  
  504.     dCobj = clCreateFromGLBuffer( Context, 0, hCobj, &status );
  505.     PrintCLError( status, "clCreateFromGLBuffer (2)" );
  506.  
  507.     // 5. create the opencl version of the velocity array:
  508.  
  509.     dVel = clCreateBuffer( Context, CL_MEM_READ_WRITE, 4*sizeof(float)*NUM_PARTICLES, NULL, &status );
  510.     PrintCLError( status, "clCreateBuffer: " );
  511.  
  512.     // 6. enqueue the command to write the data from the host buffers to the Device buffers:
  513.  
  514.     status = clEnqueueWriteBuffer( CmdQueue, dVel, CL_FALSE, 0, 4*sizeof(float)*NUM_PARTICLES, hVel, 0, NULL, NULL );
  515.     PrintCLError( status, "clEneueueWriteBuffer: " );
  516.  
  517.     // 7. read the Kernel code from a file:
  518.  
  519.     fseek( fp, 0, SEEK_END );
  520.     size_t fileSize = ftell( fp );
  521.     fseek( fp, 0, SEEK_SET );
  522.     char *clProgramText = new char[ fileSize+1 ];       // leave room for '\0'
  523.     size_t n = fread( clProgramText, 1, fileSize, fp );
  524.     clProgramText[fileSize] = '\0';
  525.     fclose( fp );
  526.  
  527.     // create the text for the Kernel Program:
  528.  
  529.     char *strings[1];
  530.     strings[0] = clProgramText;
  531.     Program = clCreateProgramWithSource( Context, 1, (const char **)strings, NULL, &status );
  532.     if( status != CL_SUCCESS )
  533.         fprintf( stderr, "clCreateProgramWithSource failed\n" );
  534.     delete [ ] clProgramText;
  535.  
  536.     // 8. compile and link the Kernel code:
  537.  
  538.     char *options = { "" };
  539.     status = clBuildProgram( Program, 1, &Device, options, NULL, NULL );
  540.     if( status != CL_SUCCESS )
  541.     {
  542.         size_t size;
  543.         clGetProgramBuildInfo( Program, Device, CL_PROGRAM_BUILD_LOG, 0, NULL, &size );
  544.         cl_char *log = new cl_char[ size ];
  545.         clGetProgramBuildInfo( Program, Device, CL_PROGRAM_BUILD_LOG, size, log, NULL );
  546.         fprintf( stderr, "clBuildProgram failed:\n%s\n", log );
  547.         delete [ ] log;
  548.     }
  549.  
  550. #ifdef  EXPORT_BINARY
  551.     size_t binary_sizes;
  552.     status = clGetProgramInfo( Program, CL_PROGRAM_BINARY_SIZES, 0, NULL, &binary_sizes );
  553.     PrintCLError( status, "clGetProgramInfo (1):" );
  554.     //fprintf( stderr, "binary_sizes = %d\n", binary_sizes );
  555.     size_t size;
  556.     status = clGetProgramInfo( Program, CL_PROGRAM_BINARY_SIZES, sizeof(size_t), &size, NULL );
  557.     PrintCLError( status, "clGetProgramInfo (2):" );
  558.     //fprintf( stderr, "size = %d\n", size );
  559.     unsigned char *binary = new unsigned char [ size ];
  560.     status = clGetProgramInfo( Program, CL_PROGRAM_BINARIES, size, &binary, NULL );
  561.     PrintCLError( status, "clGetProgramInfo (3):" );
  562.     FILE *fpbin = fopen( CL_BINARY_NAME, "wb" );
  563.     if( fpbin == NULL )
  564.     {
  565.         fprintf( stderr, "Cannot create '%s'\n", CL_BINARY_NAME );
  566.     }
  567.     else
  568.     {
  569.         fwrite( binary, 1, size, fpbin );
  570.         fclose( fpbin );
  571.         fprintf( stderr, "Binary written to '%s'\n", CL_BINARY_NAME );
  572.     }
  573.     delete [ ] binary;
  574. #endif
  575.  
  576.     // 9. create the Kernel object:
  577.  
  578.     Kernel = clCreateKernel( Program, "Particle", &status );
  579.     PrintCLError( status, "clCreateKernel failed: " );
  580.  
  581.  
  582.     // 10. setup the arguments to the Kernel object:
  583.  
  584.     status = clSetKernelArg( Kernel, 0, sizeof(cl_mem), &dPobj );
  585.     PrintCLError( status, "clSetKernelArg (1): " );
  586.  
  587.     status = clSetKernelArg( Kernel, 1, sizeof(cl_mem), &dVel );
  588.     PrintCLError( status, "clSetKernelArg (2): " );
  589.  
  590.     status = clSetKernelArg( Kernel, 2, sizeof(cl_mem), &dCobj );
  591.     PrintCLError( status, "clSetKernelArg (3): " );
  592. }
  593.  
  594.  
  595. //
  596. // initialize the glui window:
  597. //
  598.  
  599. void
  600. InitGlui( )
  601. {
  602.     glutInitWindowPosition( INIT_WINDOW_SIZE + 50, 0 );
  603.     Glui = GLUI_Master.create_glui( (char *) GLUITITLE );
  604.     Glui->add_statictext( (char *) GLUITITLE );
  605.     Glui->add_separator( );
  606.     Glui->add_checkbox( "Axes",             &AxesOn );
  607.     Glui->add_checkbox( "Perspective",      &WhichProjection );
  608.     Glui->add_checkbox( "Show Performance", &ShowPerformance );
  609.  
  610.     GLUI_Panel *panel = Glui->add_panel( "Object Transformation" );
  611.  
  612.         GLUI_Rotation *rot = Glui->add_rotation_to_panel( panel, "Rotation", (float *) RotMatrix );
  613.         rot->set_spin( 1.0 );
  614.  
  615.         Glui->add_column_to_panel( panel, GLUIFALSE );
  616.         GLUI_Translation *scale = Glui->add_translation_to_panel( panel, "Scale",  GLUI_TRANSLATION_Y , &Scale2 );
  617.         scale->set_speed( 0.01f );
  618.  
  619.         Glui->add_column_to_panel( panel, FALSE );
  620.         GLUI_Translation *trans = Glui->add_translation_to_panel( panel, "Trans XY", GLUI_TRANSLATION_XY, &TransXYZ[0] );
  621.         trans->set_speed( 1.1f );
  622.  
  623.         Glui->add_column_to_panel( panel, FALSE );
  624.         trans = Glui->add_translation_to_panel( panel, "Trans Z",  GLUI_TRANSLATION_Z , &TransXYZ[2] );
  625.         trans->set_speed( 1.1f );
  626.  
  627.     panel = Glui->add_panel( "", FALSE );
  628.         Glui->add_button_to_panel( panel, "Go !", GO, (GLUI_Update_CB) Buttons );
  629.         Glui->add_column_to_panel( panel, FALSE );
  630.         Glui->add_button_to_panel( panel, "Pause", PAUSE, (GLUI_Update_CB) Buttons );
  631.         Glui->add_column_to_panel( panel, FALSE );
  632.         Glui->add_button_to_panel( panel, "Reset", RESET, (GLUI_Update_CB) Buttons );
  633.         Glui->add_column_to_panel( panel, FALSE );
  634.         Glui->add_button_to_panel( panel, "Quit", QUIT, (GLUI_Update_CB) Buttons );
  635.  
  636.     Glui->set_main_gfx_window( MainWindow );
  637.     GLUI_Master.set_glutIdleFunc( NULL );
  638. }
  639.  
  640.  
  641.  
  642. //
  643. // initialize the glut and OpenGL libraries:
  644. //  also setup display lists and callback functions
  645. //
  646.  
  647. void
  648. InitGraphics( )
  649. {
  650.     glutInitDisplayMode( GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH );
  651.     glutInitWindowPosition( 0, 0 );
  652.     glutInitWindowSize( INIT_WINDOW_SIZE, INIT_WINDOW_SIZE );
  653.  
  654.     MainWindow = glutCreateWindow( WINDOWTITLE );
  655.     glutSetWindowTitle( WINDOWTITLE );
  656.     glClearColor( BACKCOLOR[0], BACKCOLOR[1], BACKCOLOR[2], BACKCOLOR[3] );
  657.  
  658.  
  659.     // setup the callback routines:
  660.  
  661.     glutSetWindow( MainWindow );
  662.     glutDisplayFunc( Display );
  663.     glutReshapeFunc( Resize );
  664.     glutKeyboardFunc( Keyboard );
  665.     glutMouseFunc( MouseButton );
  666.     glutMotionFunc( MouseMotion );
  667.     glutVisibilityFunc( Visibility );
  668.  
  669. #ifdef WIN32
  670.     GLenum err = glewInit();
  671.     if( err != GLEW_OK )
  672.     {
  673.         fprintf( stderr, "glewInit Error\n" );
  674.     }
  675. #endif
  676. }
  677.  
  678.  
  679.  
  680. //
  681. // initialize the display lists that will not change:
  682. //
  683.  
  684. void
  685. InitLists( )
  686. {
  687.     SphereList = glGenLists( 1 );
  688.     glNewList( SphereList, GL_COMPILE );
  689.         glColor3f( .9f, .9f, 0. );
  690.         glPushMatrix( );
  691.             glTranslatef( -100., -800., 0. );
  692.             glutWireSphere( 600., 100., 100. );
  693.         glPopMatrix( );
  694.     glEndList( );
  695.  
  696.     AxesList = glGenLists( 1 );
  697.     glNewList( AxesList, GL_COMPILE );
  698.         glColor3fv( AXES_COLOR );
  699.         glLineWidth( AXES_WIDTH );
  700.             Axes( 150. );
  701.         glLineWidth( 1. );
  702.     glEndList( );
  703. }
  704.  
  705.  
  706.  
  707. //
  708. // the keyboard callback:
  709. //
  710.  
  711. void
  712. Keyboard( unsigned char c, int x, int y )
  713. {
  714.     switch( c )
  715.     {
  716.         case 'o':
  717.         case 'O':
  718.             WhichProjection = ORTHO;
  719.             break;
  720.  
  721.         case 'p':
  722.         case 'P':
  723.             WhichProjection = PERSP;
  724.             break;
  725.  
  726.         case 'q':
  727.         case 'Q':
  728.         case ESCAPE:
  729.             Buttons( QUIT );    // will not return here
  730.             break;          // happy compiler
  731.  
  732.         default:
  733.             fprintf( stderr, "Don't know what to do with keyboard hit: '%c' (0x%0x)\n", c, c );
  734.     }
  735.     Glui->sync_live( );
  736.     glutSetWindow( MainWindow );
  737.     glutPostRedisplay( );
  738. }
  739.  
  740.  
  741.  
  742. //
  743. // called when the mouse button transitions down or up:
  744. //
  745.  
  746. void
  747. MouseButton( int button, int state, int x, int y )
  748. {
  749.     int b;          // LEFT, MIDDLE, or RIGHT
  750.    
  751.     switch( button )
  752.     {
  753.         case GLUT_LEFT_BUTTON:
  754.             b = LEFT;       break;
  755.  
  756.         case GLUT_MIDDLE_BUTTON:
  757.             b = MIDDLE;     break;
  758.  
  759.         case GLUT_RIGHT_BUTTON:
  760.             b = RIGHT;      break;
  761.  
  762.         default:
  763.             b = 0;
  764.             fprintf( stderr, "Unknown mouse button: %d\n", button );
  765.     }
  766.  
  767.  
  768.     // button down sets the bit, up clears the bit:
  769.  
  770.     if( state == GLUT_DOWN )
  771.     {
  772.         Xmouse = x;
  773.         Ymouse = y;
  774.         ActiveButton |= b;      // set the proper bit
  775.     }
  776.     else
  777.     {
  778.         ActiveButton &= ~b;     // clear the proper bit
  779.     }
  780. }
  781.  
  782.  
  783.  
  784. //
  785. // called when the mouse moves while a button is down:
  786. //
  787.  
  788. void
  789. MouseMotion( int x, int y )
  790. {
  791.     int dx = x - Xmouse;        // change in mouse coords
  792.     int dy = y - Ymouse;
  793.  
  794.     if( ActiveButton & LEFT )
  795.     {
  796.             Xrot += ( ANGFACT*dy );
  797.             Yrot += ( ANGFACT*dx );
  798.     }
  799.  
  800.  
  801.     if( ActiveButton & MIDDLE )
  802.     {
  803.         Scale += SCLFACT * (float) ( dx - dy );
  804.  
  805.         // keep object from turning inside-out or disappearing:
  806.  
  807.         if( Scale < MINSCALE )
  808.             Scale = MINSCALE;
  809.     }
  810.  
  811.     Xmouse = x;         // new current position
  812.     Ymouse = y;
  813.  
  814.     glutSetWindow( MainWindow );
  815.     glutPostRedisplay( );
  816. }
  817.  
  818.  
  819.  
  820. //
  821. // reset the transformations and the colors:
  822. //
  823. // this only sets the global variables --
  824. // the glut main loop is responsible for redrawing the scene
  825. //
  826.  
  827. void
  828. Reset( )
  829. {
  830.     ActiveButton = 0;
  831.     AxesOn = GLUIFALSE;
  832.     Paused = GLUIFALSE;
  833.     Scale  = 1.0;
  834.     Scale2 = 0.0;       // because add 1. to it in Display( )
  835.     ShowPerformance = GLUIFALSE;
  836.     WhichProjection = PERSP;
  837.     Xrot = Yrot = 0.;
  838.     TransXYZ[0] = TransXYZ[1] = TransXYZ[2] = 0.;
  839.  
  840.                       RotMatrix[0][1] = RotMatrix[0][2] = RotMatrix[0][3] = 0.;
  841.     RotMatrix[1][0]                   = RotMatrix[1][2] = RotMatrix[1][3] = 0.;
  842.     RotMatrix[2][0] = RotMatrix[2][1]                   = RotMatrix[2][3] = 0.;
  843.     RotMatrix[3][0] = RotMatrix[3][1] = RotMatrix[3][3]                   = 0.;
  844.     RotMatrix[0][0] = RotMatrix[1][1] = RotMatrix[2][2] = RotMatrix[3][3] = 1.;
  845. }
  846.  
  847.  
  848. void
  849. ResetParticles( )
  850. {
  851.     glBindBuffer( GL_ARRAY_BUFFER, hPobj );
  852.     struct xyzw *points = (struct xyzw *) glMapBuffer( GL_ARRAY_BUFFER, GL_WRITE_ONLY );
  853.     for( int i = 0; i < NUM_PARTICLES; i++ )
  854.     {
  855.         points[i].x = Ranf( XMIN, XMAX );
  856.         points[i].y = Ranf( YMIN, YMAX );
  857.         points[i].z = Ranf( ZMIN, ZMAX );
  858.         points[i].w = 1.;
  859.     }
  860.     glUnmapBuffer( GL_ARRAY_BUFFER );
  861.  
  862.  
  863.     glBindBuffer( GL_ARRAY_BUFFER, hCobj );
  864.     struct rgba *colors = (struct rgba *) glMapBuffer( GL_ARRAY_BUFFER, GL_WRITE_ONLY );
  865.     for( int i = 0; i < NUM_PARTICLES; i++ )
  866.     {
  867.         colors[i].r = Ranf( .3f, 1. );
  868.         colors[i].g = Ranf( .3f, 1. );
  869.         colors[i].b = Ranf( .3f, 1. );
  870.         colors[i].a = 1.;
  871.     }
  872.     glUnmapBuffer( GL_ARRAY_BUFFER );
  873.  
  874.  
  875.     for( int i = 0; i < NUM_PARTICLES; i++ )
  876.     {
  877.         hVel[i].x = Ranf( VMIN, VMAX );
  878.         hVel[i].y = Ranf(   0., VMAX );
  879.         hVel[i].z = Ranf( VMIN, VMAX );
  880.     }
  881. }
  882.  
  883.  
  884.  
  885. void
  886. Resize( int width, int height )
  887. {
  888.     glutSetWindow( MainWindow );
  889.     glutPostRedisplay( );
  890. }
  891.  
  892.  
  893. void
  894. Visibility ( int state )
  895. {
  896.     if( state == GLUT_VISIBLE )
  897.     {
  898.         glutSetWindow( MainWindow );
  899.         glutPostRedisplay( );
  900.     }
  901.     else
  902.     {
  903.         // could optimize by keeping track of the fact
  904.         // that the window is not visible and avoid
  905.         // animating or redrawing it ...
  906.     }
  907. }
  908.  
  909.  
  910.  
  911.  
  912.  
  913.  
  914.  
  915. // the stroke characters 'X' 'Y' 'Z' :
  916.  
  917. static float xx[ ] = {
  918.         0., 1., 0., 1.
  919.           };
  920.  
  921. static float xy[ ] = {
  922.         -.5, .5, .5, -.5
  923.           };
  924.  
  925. static int xorder[ ] = {
  926.         1, 2, -3, 4
  927.         };
  928.  
  929.  
  930. static float yx[ ] = {
  931.         0., 0., -.5, .5
  932.           };
  933.  
  934. static float yy[ ] = {
  935.         0., .6f, 1., 1.
  936.           };
  937.  
  938. static int yorder[ ] = {
  939.         1, 2, 3, -2, 4
  940.         };
  941.  
  942.  
  943. static float zx[ ] = {
  944.         1., 0., 1., 0., .25, .75
  945.           };
  946.  
  947. static float zy[ ] = {
  948.         .5, .5, -.5, -.5, 0., 0.
  949.           };
  950.  
  951. static int zorder[ ] = {
  952.         1, 2, 3, 4, -5, 6
  953.         };
  954.  
  955.  
  956. // fraction of the length to use as height of the characters:
  957.  
  958. #define LENFRAC     0.10
  959.  
  960.  
  961. // fraction of length to use as start location of the characters:
  962.  
  963. #define BASEFRAC    1.10
  964.  
  965.  
  966. //
  967. //  Draw a set of 3D axes:
  968. //  (length is the axis length in world coordinates)
  969. //
  970.  
  971. void
  972. Axes( float length )
  973. {
  974.     glBegin( GL_LINE_STRIP );
  975.         glVertex3f( length, 0., 0. );
  976.         glVertex3f( 0., 0., 0. );
  977.         glVertex3f( 0., length, 0. );
  978.     glEnd( );
  979.     glBegin( GL_LINE_STRIP );
  980.         glVertex3f( 0., 0., 0. );
  981.         glVertex3f( 0., 0., length );
  982.     glEnd( );
  983.  
  984.     float fact = LENFRAC * length;
  985.     float base = BASEFRAC * length;
  986.  
  987.     glBegin( GL_LINE_STRIP );
  988.         for( int i = 0; i < 4; i++ )
  989.         {
  990.             int j = xorder[i];
  991.             if( j < 0 )
  992.             {
  993.                
  994.                 glEnd( );
  995.                 glBegin( GL_LINE_STRIP );
  996.                 j = -j;
  997.             }
  998.             j--;
  999.             glVertex3f( base + fact*xx[j], fact*xy[j], 0.0 );
  1000.         }
  1001.     glEnd( );
  1002.  
  1003.     glBegin( GL_LINE_STRIP );
  1004.         for( int i = 0; i < 5; i++ )
  1005.         {
  1006.             int j = yorder[i];
  1007.             if( j < 0 )
  1008.             {
  1009.                
  1010.                 glEnd( );
  1011.                 glBegin( GL_LINE_STRIP );
  1012.                 j = -j;
  1013.             }
  1014.             j--;
  1015.             glVertex3f( fact*yx[j], base + fact*yy[j], 0.0 );
  1016.         }
  1017.     glEnd( );
  1018.  
  1019.     glBegin( GL_LINE_STRIP );
  1020.         for( int i = 0; i < 6; i++ )
  1021.         {
  1022.             int j = zorder[i];
  1023.             if( j < 0 )
  1024.             {
  1025.                
  1026.                 glEnd( );
  1027.                 glBegin( GL_LINE_STRIP );
  1028.                 j = -j;
  1029.             }
  1030.             j--;
  1031.             glVertex3f( 0.0, fact*zy[j], base + fact*zx[j] );
  1032.         }
  1033.     glEnd( );
  1034.  
  1035. }
  1036.  
  1037.  
  1038. //
  1039. // exit gracefully:
  1040. //
  1041.  
  1042. void
  1043. Quit( )
  1044. {
  1045.     Glui->close( );
  1046.     glutSetWindow( MainWindow );
  1047.     glFinish( );
  1048.     glutDestroyWindow( MainWindow );
  1049.  
  1050.  
  1051.     // 13. clean everything up:
  1052.  
  1053.     clReleaseKernel(        Kernel   );
  1054.     clReleaseProgram(       Program  );
  1055.     clReleaseCommandQueue(  CmdQueue );
  1056.     clReleaseMemObject(     dPobj  );
  1057.     clReleaseMemObject(     dCobj  );
  1058.  
  1059.     exit( 0 );
  1060. }
  1061.  
  1062.  
  1063.  
  1064.  
  1065. #define TOP 2147483647.     // 2^31 - 1
  1066.  
  1067. float
  1068. Ranf( float low, float high )
  1069. {
  1070.     long random( );     // returns integer 0 - TOP
  1071.  
  1072.     float r = (float)rand( );
  1073.     return(   low  +  r * ( high - low ) / (float)RAND_MAX   );
  1074. }
  1075.  
  1076.  
  1077. bool
  1078. IsCLExtensionSupported( const char *extension )
  1079. {
  1080.     // see if the extension is bogus:
  1081.  
  1082.     if( extension == NULL  ||  extension[0] == '\0' )
  1083.         return false;
  1084.  
  1085.     char * where = (char *) strchr( extension, ' ' );
  1086.     if( where != NULL )
  1087.         return false;
  1088.  
  1089.     // get the full list of extensions:
  1090.  
  1091.     size_t extensionSize;
  1092.     clGetDeviceInfo( Device, CL_DEVICE_EXTENSIONS, 0, NULL, &extensionSize );
  1093.     char *extensions = new char [extensionSize];
  1094.     clGetDeviceInfo( Device, CL_DEVICE_EXTENSIONS, extensionSize, extensions, NULL );
  1095.  
  1096.     for( char * start = extensions; ; )
  1097.     {
  1098.         where = (char *) strstr( (const char *) start, extension );
  1099.         if( where == 0 )
  1100.         {
  1101.             delete [ ] extensions;
  1102.             return false;
  1103.         }
  1104.  
  1105.         char * terminator = where + strlen(extension);  // points to what should be the separator
  1106.  
  1107.         if( *terminator == ' '  ||  *terminator == '\0'  ||  *terminator == '\r'  ||  *terminator == '\n' )
  1108.         {
  1109.             delete [ ] extensions;
  1110.             return true;
  1111.         }
  1112.         start = terminator;
  1113.     }
  1114.  
  1115.     delete [ ] extensions;
  1116.     return false;
  1117. }
  1118.  
  1119.  
  1120. struct errorcode
  1121. {
  1122.     cl_int      statusCode;
  1123.     char *      meaning;
  1124. }
  1125. ErrorCodes[ ] =
  1126. {
  1127.     { CL_SUCCESS,               ""                  },
  1128.     { CL_DEVICE_NOT_FOUND,          "Device Not Found"          },
  1129.     { CL_DEVICE_NOT_AVAILABLE,      "Device Not Available"          },
  1130.     { CL_COMPILER_NOT_AVAILABLE,        "Compiler Not Available"        },
  1131.     { CL_MEM_OBJECT_ALLOCATION_FAILURE, "Memory Object Allocation Failure"  },
  1132.     { CL_OUT_OF_RESOURCES,          "Out of resources"          },
  1133.     { CL_OUT_OF_HOST_MEMORY,        "Out of Host Memory"            },
  1134.     { CL_PROFILING_INFO_NOT_AVAILABLE,  "Profiling Information Not Available"   },
  1135.     { CL_MEM_COPY_OVERLAP,          "Memory Copy Overlap"           },
  1136.     { CL_IMAGE_FORMAT_MISMATCH,     "Image Format Mismatch"         },
  1137.     { CL_IMAGE_FORMAT_NOT_SUPPORTED,    "Image Format Not Supported"        },
  1138.     { CL_BUILD_PROGRAM_FAILURE,     "Build Program Failure"         },
  1139.     { CL_MAP_FAILURE,           "Map Failure"               },
  1140.     { CL_INVALID_VALUE,         "Invalid Value"             },
  1141.     { CL_INVALID_DEVICE_TYPE,       "Invalid Device Type"           },
  1142.     { CL_INVALID_PLATFORM,          "Invalid Platform"          },
  1143.     { CL_INVALID_DEVICE,            "Invalid Device"            },
  1144.     { CL_INVALID_CONTEXT,           "Invalid Context"           },
  1145.     { CL_INVALID_QUEUE_PROPERTIES,      "Invalid Queue Properties"      },
  1146.     { CL_INVALID_COMMAND_QUEUE,     "Invalid Command Queue"         },
  1147.     { CL_INVALID_HOST_PTR,          "Invalid Host Pointer"          },
  1148.     { CL_INVALID_MEM_OBJECT,        "Invalid Memory Object"         },
  1149.     { CL_INVALID_IMAGE_FORMAT_DESCRIPTOR,   "Invalid Image Format Descriptor"   },
  1150.     { CL_INVALID_IMAGE_SIZE,        "Invalid Image Size"            },
  1151.     { CL_INVALID_SAMPLER,           "Invalid Sampler"           },
  1152.     { CL_INVALID_BINARY,            "Invalid Binary"            },
  1153.     { CL_INVALID_BUILD_OPTIONS,     "Invalid Build Options"         },
  1154.     { CL_INVALID_PROGRAM,           "Invalid Program"           },
  1155.     { CL_INVALID_PROGRAM_EXECUTABLE,    "Invalid Program Executable"        },
  1156.     { CL_INVALID_KERNEL_NAME,       "Invalid Kernel Name"           },
  1157.     { CL_INVALID_KERNEL_DEFINITION,     "Invalid Kernel Definition"     },
  1158.     { CL_INVALID_KERNEL,            "Invalid Kernel"            },
  1159.     { CL_INVALID_ARG_INDEX,         "Invalid Argument Index"        },
  1160.     { CL_INVALID_ARG_VALUE,         "Invalid Argument Value"        },
  1161.     { CL_INVALID_ARG_SIZE,          "Invalid Argument Size"         },
  1162.     { CL_INVALID_KERNEL_ARGS,       "Invalid Kernel Arguments"      },
  1163.     { CL_INVALID_WORK_DIMENSION,        "Invalid Work Dimension"        },
  1164.     { CL_INVALID_WORK_GROUP_SIZE,       "Invalid Work Group Size"       },
  1165.     { CL_INVALID_WORK_ITEM_SIZE,        "Invalid Work Item Size"        },
  1166.     { CL_INVALID_GLOBAL_OFFSET,     "Invalid Global Offset"         },
  1167.     { CL_INVALID_EVENT_WAIT_LIST,       "Invalid Event Wait List"       },
  1168.     { CL_INVALID_EVENT,         "Invalid Event"             },
  1169.     { CL_INVALID_OPERATION,         "Invalid Operation"         },
  1170.     { CL_INVALID_GL_OBJECT,         "Invalid GL Object"         },
  1171.     { CL_INVALID_BUFFER_SIZE,       "Invalid Buffer Size"           },
  1172.     { CL_INVALID_MIP_LEVEL,         "Invalid MIP Level"         },
  1173.     { CL_INVALID_GLOBAL_WORK_SIZE,      "Invalid Global Work Size"      },
  1174. };
  1175.  
  1176. void
  1177. PrintCLError( cl_int errorCode, char * prefix, FILE *fp )
  1178. {
  1179.     if( errorCode == CL_SUCCESS )
  1180.         return;
  1181.    
  1182.     const int numErrorCodes = sizeof( ErrorCodes ) / sizeof( struct errorcode );
  1183.     char * meaning = "";
  1184.     for( int i = 0; i < numErrorCodes; i++ )
  1185.     {
  1186.         if( errorCode == ErrorCodes[i].statusCode )
  1187.         {
  1188.             meaning = ErrorCodes[i].meaning;
  1189.             break;
  1190.         }
  1191.     }
  1192.  
  1193.     fprintf( fp, "%s %s\n", prefix, meaning );
  1194. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement