本文要解决的问题是如何实现CUDA和OpenGL的互操作,使得GPU能够将通用计算的运算结果交给OpenGL进行绘制。

本文的应用程序主要包括两个方面:

1.      使用CUDA核函数生成图像数据

2.      将数据传递给OpenGL驱动程序并进行渲染

实现这个功能需要按如下四个步骤:

Step1: 申明两个全局变量,保存指向同一个缓冲区的不同句柄,指向要在OpenGL和CUDA之间共享的数据;

Step2: 选择运行应用程序的CUDA设备(cudaChooseDevice),告诉cuda运行时使用哪个设备来执行CUDA和OpenGL (cudaGLSetGLDevice);

Step3:在OpenGL中创建像素缓冲区对象;

Step4: 通知CUDA运行时将像素缓冲区对象bufferObj注册为图形资源,实现缓冲区共享。

然后就可以按照一般的CUDA程序调用核函数进行计算。运行结果如下:

/********************************************************************
* SharedBuffer.cu
* interact between CUDA and OpenGL
*********************************************************************/ #include <stdio.h>
#include <stdlib.h>
#include "GL\glut.h"
#include "GL\glext.h"
#include <cuda_runtime.h>
#include <cutil_inline.h>
#include <cuda.h>
#include <cuda_gl_interop.h> #define GET_PROC_ADDRESS(str) wglGetProcAddress(str)
#define DIM 512 PFNGLBINDBUFFERARBPROC glBindBuffer = NULL;
PFNGLDELETEBUFFERSARBPROC glDeleteBuffers = NULL;
PFNGLGENBUFFERSARBPROC glGenBuffers = NULL;
PFNGLBUFFERDATAARBPROC glBufferData = NULL; // step one:
GLuint bufferObj;
cudaGraphicsResource *resource; __global__ void cudaGLKernel(uchar4 *ptr)
{
int x = threadIdx.x + blockIdx.x * blockDim.x;
int y = threadIdx.y + blockIdx.y * blockDim.y;
int offset = x + y * blockDim.x * gridDim.x; float fx = x/(float)DIM - 0.5f;
float fy = y/(float)DIM - 0.5f; unsigned char green = + * sin(abs(fx*) - abs(fy*)); ptr[offset].x = ;
ptr[offset].y = green;
ptr[offset].z = ;
ptr[offset].w = ; } void drawFunc(void)
{
glDrawPixels(DIM, DIM, GL_RGBA, GL_UNSIGNED_BYTE, );
glutSwapBuffers();
} static void keyFunc(unsigned char key, int x, int y)
{
switch(key){
case :
cutilSafeCall(cudaGraphicsUnregisterResource(resource));
glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, );
glDeleteBuffers(, &bufferObj);
exit();
}
} int main(int argc, char* argv[])
{
// step 2:
cudaDeviceProp prop;
int dev; memset(&prop, , sizeof(cudaDeviceProp));
prop.major = ;
prop.minor = ;
cutilSafeCall(cudaChooseDevice(&dev, &prop));
cutilSafeCall(cudaGLSetGLDevice(dev)); glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA);
glutInitWindowSize(DIM, DIM);
glutCreateWindow("CUDA interact with OpenGL"); // step 3:
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(, &bufferObj);
glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, bufferObj);
glBufferData(GL_PIXEL_UNPACK_BUFFER_ARB, DIM*DIM*, NULL, GL_DYNAMIC_DRAW_ARB); // step 4:
cutilSafeCall(cudaGraphicsGLRegisterBuffer(&resource, bufferObj, cudaGraphicsMapFlagsNone)); uchar4* devPtr;
size_t size;
cutilSafeCall(cudaGraphicsMapResources(, &resource, NULL));
cutilSafeCall(cudaGraphicsResourceGetMappedPointer((void**)&devPtr, &size, resource)); dim3 grids(DIM/, DIM/);
dim3 threads(, );
cudaGLKernel<<<grids, threads>>>(devPtr); cutilSafeCall(cudaGraphicsUnmapResources(, &resource, NULL));
glutKeyboardFunc(keyFunc);
glutDisplayFunc(drawFunc);
glutMainLoop();
return ;
}

程序编译的时候貌似要注意头文件glut.h和glext.h的顺序,否则会报错~

参考资源:

1、Jason Sanders, Edward Kandrot, CUDA By Example: An Introduction toGeneral-Purpose GPU Programming (2011).该书电子版下载源码下载

2、[菜鸟每天来段CUDA_C]CUDA与OpenGL互操作

3、CUDA与OpenGL交互开发

4、cuda与opengl互操作之PBO

最新文章

  1. sql关于Group by
  2. 【iOS】配置和使用静态库
  3. Linux系统资源使用情况
  4. 拷贝数据库和VS项目
  5. bootstrap ace treeview树表
  6. Java基础(2):Java中的四个跳转语句总结goto,break,continue,return
  7. Windows Tomcat 安装
  8. 认识Java虚拟机的内部体系结构、gc示例
  9. mysqldump原理3
  10. PHP安装OPENSSL扩展模块
  11. ios应用接入微信开放平台
  12. frameset框架样式 加边框
  13. php中header函数参数的 Cache-control:private,no-cache,must-revalidate,max-age 使用方法
  14. JAVA基础知识(2)--队列的操作
  15. 简易版jQuery——mQuery
  16. npm的使用总结
  17. webapi 控制json的字段(key)显示顺序
  18. C# DateTimePicker控件获取他的年,月,日,时,分,秒
  19. vue.js 树菜单 递归组件树来实现
  20. win10安装pycharm及汉化包

热门文章

  1. java 散列运算浅分析 hash()
  2. Map常用集合遍历
  3. hibernate5的一些坑
  4. Maven pom.xml 常用打包配置
  5. img 加载网络图片失败 显示默认图片
  6. JavaScript 数组对象常用属性
  7. QQ 聊天机器人小薇 1.0.1 发布!
  8. C# CRC16算法实现【转】
  9. Tesseract-OCR-05-主要API功能介绍
  10. Tesseract-OCR-02-Tesseract-OCR 的安装与 环境变量配置