《GPU高性能编程CUDA实战》是一本不错的好书,其中所含示例代码,经常包含有 "gpu_anim.h"等头文件, 为方便学习者查找,将头文件 “gpu_anim.h” 分享在这里。
/* * Copyright 1993-2010 NVIDIA Corporation. All rights reserved. * * NVIDIA Corporation and its licensors retain all intellectual property and * proprietary rights in and to this software and related documentation. * Any use, reproduction, disclosure, or distribution of this software * and related documentation without an express license agreement from * NVIDIA Corporation is strictly prohibited. * * Please refer to the applicable NVIDIA end user license agreement (EULA) * associated with this source code for terms and conditions that govern * your use of this NVIDIA software. * */ #ifndef __GPU_ANIM_H__ #define __GPU_ANIM_H__ #include "gl_helper.h" #include "cuda.h" #include "cuda_gl_interop.h" #include <iostream> PFNGLBINDBUFFERARBPROC glBindBuffer = NULL; PFNGLDELETEBUFFERSARBPROC glDeleteBuffers = NULL; PFNGLGENBUFFERSARBPROC glGenBuffers = NULL; PFNGLBUFFERDATAARBPROC glBufferData = NULL; struct GPUAnimBitmap { GLuint bufferObj; cudaGraphicsResource *resource; int width, height; void *dataBlock; void (*fAnim)(uchar4*,void*,int); void (*animExit)(void*); void (*clickDrag)(void*,int,int,int,int); int dragStartX, dragStartY; GPUAnimBitmap( int w, int h, void *d = NULL ) { width = w; height = h; dataBlock = d; clickDrag = NULL; // first, find a CUDA device and set it to graphic interop cudaDeviceProp prop; int dev; memset( &prop, 0, sizeof( cudaDeviceProp ) ); prop.major = 1; prop.minor = 0; HANDLE_ERROR( cudaChooseDevice( &dev, &prop ) ); cudaGLSetGLDevice( dev ); // a bug in the Windows GLUT implementation prevents us from // passing zero arguments to glutInit() int c=1; char* dummy = ""; glutInit( &c, &dummy ); glutInitDisplayMode( GLUT_DOUBLE | GLUT_RGBA ); glutInitWindowSize( width, height ); glutCreateWindow( "bitmap" ); glBindBuffer = (PFNGLBINDBUFFERARBPROC)GET_PROC_ADDRESS("glBindBuffer"); glDeleteBuffers = (PFNGLDELETEBUFFERSARBPROC)GET_PROC_ADDRESS("glDeleteBuffers"); glGenBuffers = (PFNGLGENBUFFERSARBPROC)GET_PROC_ADDRESS("glGenBuffers"); glBufferData = (PFNGLBUFFERDATAARBPROC)GET_PROC_ADDRESS("glBufferData"); glGenBuffers( 1, &bufferObj ); glBindBuffer( GL_PIXEL_UNPACK_BUFFER_ARB, bufferObj ); glBufferData( GL_PIXEL_UNPACK_BUFFER_ARB, width * height * 4, NULL, GL_DYNAMIC_DRAW_ARB ); HANDLE_ERROR( cudaGraphicsGLRegisterBuffer( &resource, bufferObj, cudaGraphicsMapFlagsNone ) ); } ~GPUAnimBitmap() { free_resources(); } void free_resources( void ) { HANDLE_ERROR( cudaGraphicsUnregisterResource( resource ) ); glBindBuffer( GL_PIXEL_UNPACK_BUFFER_ARB, 0 ); glDeleteBuffers( 1, &bufferObj ); } long image_size( void ) const { return width * height * 4; } void click_drag( void (*f)(void*,int,int,int,int)) { clickDrag = f; } void anim_and_exit( void (*f)(uchar4*,void*,int), void(*e)(void*) ) { GPUAnimBitmap** bitmap = get_bitmap_ptr(); *bitmap = this; fAnim = f; animExit = e; glutKeyboardFunc( Key ); glutDisplayFunc( Draw ); if (clickDrag != NULL) glutMouseFunc( mouse_func ); glutIdleFunc( idle_func ); glutMainLoop(); } // static method used for glut callbacks static GPUAnimBitmap** get_bitmap_ptr( void ) { static GPUAnimBitmap* gBitmap; return &gBitmap; } // static method used for glut callbacks static void mouse_func( int button, int state, int mx, int my ) { if (button == GLUT_LEFT_BUTTON) { GPUAnimBitmap* bitmap = *(get_bitmap_ptr()); if (state == GLUT_DOWN) { bitmap->dragStartX = mx; bitmap->dragStartY = my; } else if (state == GLUT_UP) { bitmap->clickDrag( bitmap->dataBlock, bitmap->dragStartX, bitmap->dragStartY, mx, my ); } } } // static method used for glut callbacks static void idle_func( void ) { static int ticks = 1; GPUAnimBitmap* bitmap = *(get_bitmap_ptr()); uchar4* devPtr; size_t size; HANDLE_ERROR( cudaGraphicsMapResources( 1, &(bitmap->resource), NULL ) ); HANDLE_ERROR( cudaGraphicsResourceGetMappedPointer( (void**)&devPtr, &size, bitmap->resource) ); bitmap->fAnim( devPtr, bitmap->dataBlock, ticks++ ); HANDLE_ERROR( cudaGraphicsUnmapResources( 1, &(bitmap->resource), NULL ) ); glutPostRedisplay(); } // static method used for glut callbacks static void Key(unsigned char key, int x, int y) { switch (key) { case 27: GPUAnimBitmap* bitmap = *(get_bitmap_ptr()); if (bitmap->animExit) bitmap->animExit( bitmap->dataBlock ); bitmap->free_resources(); exit(0); } } // static method used for glut callbacks static void Draw( void ) { GPUAnimBitmap* bitmap = *(get_bitmap_ptr()); glClearColor( 0.0, 0.0, 0.0, 1.0 ); glClear( GL_COLOR_BUFFER_BIT ); glDrawPixels( bitmap->width, bitmap->height, GL_RGBA, GL_UNSIGNED_BYTE, 0 ); glutSwapBuffers(); } }; #endif // __GPU_ANIM_H__