proffreda

OpenGl code

May 8th, 2016
119
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 16.51 KB | None | 0 0
  1. nvcc –O3 -L CUDA_LIBRARIES -I CUDA_INCLUDES simpleGLmain.cpp simplePBO.cpp callbacksPBO.cpp kernelPBO.cu -lglut -lGLEW –lcutil –o testpattern
  2.  
  3. // simpleGLmain.cpp (Rob Farber)
  4. // includes
  5. #include <GL/glew.h>
  6. #include <cuda_runtime.h>
  7. #include <cutil_inline.h>
  8. #include <cutil_gl_inline.h>
  9. #include <cutil_gl_error.h>
  10. #include <cuda_gl_interop.h>
  11. #include <rendercheck_gl.h>
  12.  
  13. // The user must create the following routines:
  14. // CUDA methods
  15. extern void initCuda(int argc, char** argv);
  16. extern void runCuda();
  17. extern void renderCuda(int);
  18.  
  19. // callbacks
  20. extern void display();
  21. extern void keyboard(unsigned char key, int x, int y);
  22. extern void mouse(int button, int state, int x, int y);
  23. extern void motion(int x, int y);
  24.  
  25. // GLUT specific variables
  26. unsigned int window_width = 512;
  27. unsigned int window_height = 512;
  28.  
  29. unsigned int timer = 0; // a timer for FPS calculations
  30.  
  31. // Forward declarations of GL functionality
  32. CUTBoolean initGL(int argc, char** argv);
  33.  
  34. // Simple method to display the Frames Per Second in the window title
  35. void computeFPS()
  36. {
  37. static int fpsCount=0;
  38. static int fpsLimit=100;
  39.  
  40. fpsCount++;
  41.  
  42. if (fpsCount == fpsLimit) {
  43. char fps[256];
  44. float ifps = 1.f / (cutGetAverageTimerValue(timer) / 1000.f);
  45. sprintf(fps, "Cuda GL Interop Wrapper: %3.1f fps ", ifps);
  46.  
  47. glutSetWindowTitle(fps);
  48. fpsCount = 0;
  49.  
  50. cutilCheckError(cutResetTimer(timer));
  51. }
  52. }
  53.  
  54. void fpsDisplay()
  55. {
  56. cutilCheckError(cutStartTimer(timer));
  57.  
  58. display();
  59.  
  60. cutilCheckError(cutStopTimer(timer));
  61. computeFPS();
  62. }
  63.  
  64. // Main program
  65. int main(int argc, char** argv)
  66. {
  67. // Create the CUTIL timer
  68. cutilCheckError( cutCreateTimer( &timer));
  69.  
  70. if (CUTFalse == initGL(argc, argv)) {
  71. return CUTFalse;
  72. }
  73.  
  74. initCuda(argc, argv);
  75. CUT_CHECK_ERROR_GL();
  76.  
  77. // register callbacks
  78. glutDisplayFunc(fpsDisplay);
  79. glutKeyboardFunc(keyboard);
  80. glutMouseFunc(mouse);
  81. glutMotionFunc(motion);
  82.  
  83. // start rendering mainloop
  84. glutMainLoop();
  85.  
  86. // clean up
  87. cudaThreadExit();
  88. cutilExit(argc, argv);
  89. }
  90.  
  91. CUTBoolean initGL(int argc, char **argv)
  92. {
  93. //Steps 1-2: create a window and GL context (also register callbacks)
  94. glutInit(&argc, argv);
  95. glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);
  96. glutInitWindowSize(window_width, window_height);
  97. glutCreateWindow("Cuda GL Interop Demo (adapted from NVIDIA's simpleGL");
  98. glutDisplayFunc(fpsDisplay);
  99. glutKeyboardFunc(keyboard);
  100. glutMotionFunc(motion);
  101.  
  102. // check for necessary OpenGL extensions
  103. glewInit();
  104. if (! glewIsSupported( "GL_VERSION_2_0 " ) ) {
  105. fprintf(stderr, "ERROR: Support for necessary OpenGL extensions missing.");
  106. return CUTFalse;
  107. }
  108.  
  109. // Step 3: Setup our viewport and viewing modes
  110. glViewport(0, 0, window_width, window_height);
  111.  
  112. glClearColor(0.0, 0.0, 0.0, 1.0);
  113. glDisable(GL_DEPTH_TEST);
  114.  
  115.  
  116. // set view matrix
  117. glMatrixMode(GL_MODELVIEW);
  118. glLoadIdentity();
  119.  
  120. glMatrixMode(GL_PROJECTION);
  121. glLoadIdentity();
  122. glOrtho(0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f);
  123.  
  124. return CUTTrue;
  125. }
  126.  
  127.  
  128. //Steps 1-2: create a window and GL context (also register callbacks)
  129. glutInit(&argc, argv);
  130. glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);
  131. glutInitWindowSize(window_width, window_height);
  132. glutCreateWindow("Cuda GL Interop Demo (adapted from NVIDIA's simpleGL");
  133. glutDisplayFunc(fpsDisplay);
  134. glutKeyboardFunc(keyboard);
  135. glutMotionFunc(motion);
  136.  
  137. // check for necessary OpenGL extensions
  138. glewInit();
  139. if (! glewIsSupported( "GL_VERSION_2_0 " ) ) {
  140. fprintf(stderr, "ERROR: Support for necessary OpenGL extensions missing.");
  141. return CUTFalse;
  142. }
  143.  
  144. // Step 3: Setup our viewport and viewing modes
  145. glViewport(0, 0, window_width, window_height);
  146.  
  147. glClearColor(0.0, 0.0, 0.0, 1.0);
  148. glDisable(GL_DEPTH_TEST);
  149.  
  150. // set view matrix
  151. glMatrixMode(GL_MODELVIEW);
  152. glLoadIdentity();
  153.  
  154. glMatrixMode(GL_PROJECTION);
  155. glLoadIdentity();
  156. glOrtho(0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f);
  157.  
  158.  
  159.  
  160. /////////////////////////////////////////////////////////////////////
  161. //kernelPBO.cu (Rob Farber)
  162.  
  163. #include <stdio.h>
  164.  
  165. void checkCUDAError(const char *msg) {
  166. cudaError_t err = cudaGetLastError();
  167. if( cudaSuccess != err) {
  168. fprintf(stderr, "Cuda error: %s: %s.\n", msg, cudaGetErrorString( err) );
  169. exit(EXIT_FAILURE);
  170. }
  171. }
  172.  
  173. //Simple kernel writes changing colors to a uchar4 array
  174. __global__ void kernel(uchar4* pos, unsigned int width, unsigned int height,
  175. float time)
  176. {
  177. int index = blockIdx.x * blockDim.x + threadIdx.x;
  178. unsigned int x = index%width;
  179. unsigned int y = index/width;
  180.  
  181. if(index < width*height) {
  182. unsigned char r = (x + (int) time)&0xff;
  183. unsigned char g = (y + (int) time)&0xff;
  184. unsigned char b = ((x+y) + (int) time)&0xff;
  185.  
  186. // Each thread writes one pixel location in the texture (textel)
  187. pos[index].w = 0;
  188. pos[index].x = r;
  189. pos[index].y = g;
  190. pos[index].z = b;
  191. }
  192. }
  193.  
  194. // Wrapper for the __global__ call that sets up the kernel call
  195. extern "C" void launch_kernel(uchar4* pos, unsigned int image_width,
  196. unsigned int image_height, float time)
  197. {
  198. // execute the kernel
  199. int nThreads=256;
  200. int totalThreads = image_height * image_width;
  201. int nBlocks = totalThreads/nThreads;
  202. nBlocks += ((totalThreads%nThreads)>0)?1:0;
  203.  
  204. kernel<<< nBlocks, nThreads>>>(pos, image_width, image_height, time);
  205.  
  206. // make certain the kernel has completed
  207. cudaThreadSynchronize();
  208.  
  209. checkCUDAError("kernel failed!");
  210. }
  211.  
  212.  
  213.  
  214.  
  215. /////////////////////////////////////////////////////////
  216. //callbacksPBO.cpp (Rob Farber)
  217.  
  218. #include <GL/glew.h>
  219. #include <cuda_runtime.h>
  220. #include <cutil_inline.h>
  221. #include <cutil_gl_inline.h>
  222. #include <cuda_gl_interop.h>
  223. //#include <cutil_gl_error.h>
  224. #include <rendercheck_gl.h>
  225.  
  226. // variables for keyboard control
  227. int animFlag=1;
  228. float animTime=0.0f;
  229. float animInc=0.1f;
  230.  
  231. //external variables
  232. extern GLuint pbo;
  233. extern GLuint textureID;
  234. extern unsigned int image_width;
  235. extern unsigned int image_height;
  236.  
  237. // The user must create the following routines:
  238. void runCuda();
  239.  
  240. void display()
  241. {
  242. // run CUDA kernel
  243. runCuda();
  244.  
  245. // Create a texture from the buffer
  246. glBindBuffer( GL_PIXEL_UNPACK_BUFFER, pbo);
  247.  
  248. // bind texture from PBO
  249. glBindTexture(GL_TEXTURE_2D, textureID);
  250.  
  251.  
  252. // Note: glTexSubImage2D will perform a format conversion if the
  253. // buffer is a different format from the texture. We created the
  254. // texture with format GL_RGBA8. In glTexSubImage2D we specified
  255. // GL_BGRA and GL_UNSIGNED_INT. This is a fast-path combination
  256.  
  257. // Note: NULL indicates the data resides in device memory
  258. glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, image_width, image_height,
  259. GL_RGBA, GL_UNSIGNED_BYTE, NULL);
  260.  
  261.  
  262. // Draw a single Quad with texture coordinates for each vertex.
  263.  
  264. glBegin(GL_QUADS);
  265. glTexCoord2f(0.0f,1.0f); glVertex3f(0.0f,0.0f,0.0f);
  266. glTexCoord2f(0.0f,0.0f); glVertex3f(0.0f,1.0f,0.0f);
  267. glTexCoord2f(1.0f,0.0f); glVertex3f(1.0f,1.0f,0.0f);
  268. glTexCoord2f(1.0f,1.0f); glVertex3f(1.0f,0.0f,0.0f);
  269. glEnd();
  270.  
  271. // Don't forget to swap the buffers!
  272. glutSwapBuffers();
  273.  
  274. // if animFlag is true, then indicate the display needs to be redrawn
  275. if(animFlag) {
  276. glutPostRedisplay();
  277. animTime += animInc;
  278. }
  279. }
  280.  
  281. //! Keyboard events handler for GLUT
  282. void keyboard(unsigned char key, int x, int y)
  283. {
  284. switch(key) {
  285. case(27) :
  286. exit(0);
  287. break;
  288. case 'a': // toggle animation
  289. case 'A':
  290. animFlag = (animFlag)?0:1;
  291. break;
  292. case '-': // decrease the time increment for the CUDA kernel
  293. animInc -= 0.01;
  294. break;
  295. case '+': // increase the time increment for the CUDA kernel
  296. animInc += 0.01;
  297. break;
  298. case 'r': // reset the time increment
  299. animInc = 0.01;
  300. break;
  301. }
  302.  
  303. // indicate the display must be redrawn
  304. glutPostRedisplay();
  305. }
  306.  
  307. // No mouse event handlers defined
  308. void mouse(int button, int state, int x, int y)
  309. {
  310. }
  311.  
  312. void motion(int x, int y)
  313. {
  314. }
  315.  
  316. // Create a texture from the buffer
  317. glBindBuffer( GL_PIXEL_UNPACK_BUFFER, pbo);
  318.  
  319. // bind texture from PBO
  320. glBindTexture(GL_TEXTURE_2D, textureID);
  321.  
  322.  
  323. // Note: glTexSubImage2D will perform a format conversion if the
  324. // buffer is a different format from the texture. We created the
  325. // texture with format GL_RGBA8. In glTexSubImage2D we specified
  326. // GL_BGRA and GL_UNSIGNED_INT. This is a fast-path combination
  327.  
  328. // Note: NULL indicates the data resides in device memory
  329. glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, image_width, image_height,
  330. GL_RGBA, GL_UNSIGNED_BYTE, NULL);
  331.  
  332.  
  333.  
  334.  
  335.  
  336.  
  337. ///////////////////////////////////////////////////////////////////////
  338. // simplePBO.cpp (Rob Farber)
  339.  
  340. // includes
  341. #include <GL/glew.h>
  342. #include <cuda_runtime.h>
  343. #include <cutil_inline.h>
  344. #include <cutil_gl_inline.h>
  345. #include <cuda_gl_interop.h>
  346. #include <rendercheck_gl.h>
  347.  
  348. // external variables
  349. extern float animTime;
  350. extern unsigned int window_width;
  351. extern unsigned int window_height;
  352.  
  353. // constants (the following should be a const in a header file)
  354. unsigned int image_width = window_width;
  355. unsigned int image_height = window_height;
  356.  
  357. extern "C" void launch_kernel(uchar4* , unsigned int, unsigned int, float);
  358.  
  359. // variables
  360. GLuint pbo=NULL;
  361. GLuint textureID=NULL;
  362.  
  363. void createPBO(GLuint* pbo)
  364. {
  365.  
  366. if (pbo) {
  367. // set up vertex data parameter
  368. int num_texels = image_width * image_height;
  369. int num_values = num_texels * 4;
  370. int size_tex_data = sizeof(GLubyte) * num_values;
  371.  
  372. // Generate a buffer ID called a PBO (Pixel Buffer Object)
  373. glGenBuffers(1,pbo);
  374. // Make this the current UNPACK buffer (OpenGL is state-based)
  375. glBindBuffer(GL_PIXEL_UNPACK_BUFFER, *pbo);
  376. // Allocate data for the buffer. 4-channel 8-bit image
  377. glBufferData(GL_PIXEL_UNPACK_BUFFER, size_tex_data, NULL, GL_DYNAMIC_COPY);
  378. cudaGLRegisterBufferObject( *pbo );
  379. }
  380. }
  381.  
  382. void deletePBO(GLuint* pbo)
  383. {
  384. if (pbo) {
  385. // unregister this buffer object with CUDA
  386. cudaGLUnregisterBufferObject(*pbo);
  387.  
  388. glBindBuffer(GL_ARRAY_BUFFER, *pbo);
  389. glDeleteBuffers(1, pbo);
  390.  
  391. *pbo = NULL;
  392. }
  393. }
  394.  
  395. void createTexture(GLuint* textureID, unsigned int size_x, unsigned int size_y)
  396. {
  397. // Enable Texturing
  398. glEnable(GL_TEXTURE_2D);
  399.  
  400. // Generate a texture identifier
  401. glGenTextures(1,textureID);
  402.  
  403. // Make this the current texture (remember that GL is state-based)
  404. glBindTexture( GL_TEXTURE_2D, *textureID);
  405.  
  406. // Allocate the texture memory. The last parameter is NULL since we only
  407. // want to allocate memory, not initialize it
  408. glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA8, image_width, image_height, 0,
  409. GL_BGRA,GL_UNSIGNED_BYTE, NULL);
  410.  
  411. // Must set the filter mode, GL_LINEAR enables interpolation when scaling
  412. glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
  413. glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
  414. // Note: GL_TEXTURE_RECTANGLE_ARB may be used instead of
  415. // GL_TEXTURE_2D for improved performance if linear interpolation is
  416. // not desired. Replace GL_LINEAR with GL_NEAREST in the
  417. // glTexParameteri() call
  418.  
  419. }
  420.  
  421. void deleteTexture(GLuint* tex)
  422. {
  423. glDeleteTextures(1, tex);
  424.  
  425. *tex = NULL;
  426. }
  427.  
  428. void cleanupCuda()
  429. {
  430. if(pbo) deletePBO(&pbo);
  431. if(textureID) deleteTexture(&textureID);
  432. }
  433.  
  434. // Run the Cuda part of the computation
  435. void runCuda()
  436. {
  437. uchar4 *dptr=NULL;
  438.  
  439. // map OpenGL buffer object for writing from CUDA on a single GPU
  440. // no data is moved (Win & Linux). When mapped to CUDA, OpenGL
  441. // should not use this buffer
  442. cudaGLMapBufferObject((void**)&dptr, pbo);
  443.  
  444. // execute the kernel
  445. launch_kernel(dptr, image_width, image_height, animTime);
  446.  
  447. // unmap buffer object
  448. cudaGLUnmapBufferObject(pbo);
  449. }
  450.  
  451. void initCuda(int argc, char** argv)
  452. {
  453. // First initialize OpenGL context, so we can properly set the GL
  454. // for CUDA. NVIDIA notes this is necessary in order to achieve
  455. // optimal performance with OpenGL/CUDA interop. use command-line
  456. // specified CUDA device, otherwise use device with highest Gflops/s
  457. if( cutCheckCmdLineFlag(argc, (const char**)argv, "device") ) {
  458. cutilGLDeviceInit(argc, argv);
  459. } else {
  460. cudaGLSetGLDevice( cutGetMaxGflopsDeviceId() );
  461. }
  462.  
  463. createPBO(&pbo);
  464. createTexture(&textureID,image_width,image_height);
  465.  
  466. // Clean up on program exit
  467. atexit(cleanupCuda);
  468.  
  469. runCuda();
  470. }
  471.  
  472.  
  473. //////////////////////////////////////////////////////////////////
  474. //callbacksPBO.cpp (Rob Farber)
  475.  
  476. #include <GL/glew.h>
  477. #include <cuda_runtime.h>
  478. #include <cutil_inline.h>
  479. #include <cutil_gl_inline.h>
  480. #include <cuda_gl_interop.h>
  481. //#include <cutil_gl_error.h>
  482. #include <rendercheck_gl.h>
  483.  
  484. // variables for keyboard control
  485. int animFlag=1;
  486. float animTime=0.0f;
  487. float animInc=0.1f;
  488.  
  489. //external variables
  490. extern GLuint pbo;
  491. extern GLuint textureID;
  492. extern unsigned int image_width;
  493. extern unsigned int image_height;
  494.  
  495. // The user must create the following routines:
  496. void runCuda();
  497.  
  498. void display()
  499. {
  500. // run CUDA kernel
  501. runCuda();
  502.  
  503. // Create a texture from the buffer
  504. glBindBuffer( GL_PIXEL_UNPACK_BUFFER, pbo);
  505.  
  506. // bind texture from PBO
  507. glBindTexture(GL_TEXTURE_2D, textureID);
  508.  
  509.  
  510. // Note: glTexSubImage2D will perform a format conversion if the
  511. // buffer is a different format from the texture. We created the
  512. // texture with format GL_RGBA8. In glTexSubImage2D we specified
  513. // GL_BGRA and GL_UNSIGNED_INT. This is a fast-path combination
  514.  
  515. // Note: NULL indicates the data resides in device memory
  516. glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, image_width, image_height,
  517. GL_RGBA, GL_UNSIGNED_BYTE, NULL);
  518.  
  519.  
  520. // Draw a single Quad with texture coordinates for each vertex.
  521.  
  522. glBegin(GL_QUADS);
  523. glTexCoord2f(0.0f,1.0f); glVertex3f(0.0f,0.0f,0.0f);
  524. glTexCoord2f(0.0f,0.0f); glVertex3f(0.0f,1.0f,0.0f);
  525. glTexCoord2f(1.0f,0.0f); glVertex3f(1.0f,1.0f,0.0f);
  526. glTexCoord2f(1.0f,1.0f); glVertex3f(1.0f,0.0f,0.0f);
  527. glEnd();
  528.  
  529. // Don't forget to swap the buffers!
  530. glutSwapBuffers();
  531.  
  532. // if animFlag is true, then indicate the display needs to be redrawn
  533. if(animFlag) {
  534. glutPostRedisplay();
  535. animTime += animInc;
  536. }
  537. }
  538.  
  539. //! Keyboard events handler for GLUT
  540. void keyboard(unsigned char key, int x, int y)
  541. {
  542. switch(key) {
  543. case(27) :
  544. exit(0);
  545. break;
  546. case 'a': // toggle animation
  547. case 'A':
  548. animFlag = (animFlag)?0:1;
  549. break;
  550. case '-': // decrease the time increment for the CUDA kernel
  551. animInc -= 0.01;
  552. break;
  553. case '+': // increase the time increment for the CUDA kernel
  554. animInc += 0.01;
  555. break;
  556. case 'r': // reset the time increment
  557. animInc = 0.01;
  558. break;
  559. }
  560.  
  561. // indicate the display must be redrawn
  562. glutPostRedisplay();
  563. }
  564.  
  565. // No mouse event handlers defined
  566. void mouse(int button, int state, int x, int y)
  567. {
  568. }
  569.  
  570. void motion(int x, int y)
  571. {
  572. }
  573.  
  574.  
  575.  
  576. /////////////////////////////////////////////////////////
  577. //kernelPBO.cu (Rob Farber)
  578.  
  579. #include <stdio.h>
  580.  
  581. void checkCUDAError(const char *msg) {
  582. cudaError_t err = cudaGetLastError();
  583. if( cudaSuccess != err) {
  584. fprintf(stderr, "Cuda error: %s: %s.\n", msg, cudaGetErrorString( err) );
  585. exit(EXIT_FAILURE);
  586. }
  587. }
  588.  
  589. //Simple kernel writes changing colors to a uchar4 array
  590. __global__ void kernel(uchar4* pos, unsigned int width, unsigned int height,
  591. float time)
  592. {
  593. int index = blockIdx.x * blockDim.x + threadIdx.x;
  594. unsigned int x = index%width;
  595. unsigned int y = index/width;
  596.  
  597. if(index < width*height) {
  598. unsigned char r = (x + (int) time)&0xff;
  599. unsigned char g = (y + (int) time)&0xff;
  600. unsigned char b = ((x+y) + (int) time)&0xff;
  601.  
  602. // Each thread writes one pixel location in the texture (textel)
  603. pos[index].w = 0;
  604. pos[index].x = r;
  605. pos[index].y = g;
  606. pos[index].z = b;
  607. }
  608. }
  609.  
  610. // Wrapper for the __global__ call that sets up the kernel call
  611. extern "C" void launch_kernel(uchar4* pos, unsigned int image_width,
  612. unsigned int image_height, float time)
  613. {
  614. // execute the kernel
  615. int nThreads=256;
  616. int totalThreads = image_height * image_width;
  617. int nBlocks = totalThreads/nThreads;
  618. nBlocks += ((totalThreads%nThreads)>0)?1:0;
  619.  
  620. kernel<<< nBlocks, nThreads>>>(pos, image_width, image_height, time);
  621.  
  622. // make certain the kernel has completed
  623. cudaThreadSynchronize();
  624.  
  625. checkCUDAError("kernel failed!");
  626. }
Add Comment
Please, Sign In to add comment