CUDA与OpenGL互操作实例
本文要解决的问题是如何实现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互操作
CUDA与OpenGL互操作实例的更多相关文章
- [转]CUDA和OpenGL互操作的实现及分析
CUDA和OpenGL互操作的实现及分析刘进锋.郭雷(西北工业大学 自动化学院,陕西西安710129) 1 CUDA与OpenGL概述 OpenGL是图形硬件的软件接口,它是在SGI等多家世界著名的计 ...
- CUDA与OpenGL互操作
当处理较大数据量的时候,往往会用GPU进行运算,比如OpenGL或者CUDA.在实际的操作中,往往CUDA实现并行计算会比OpenGL更加方便,而OpenGL在进行后期渲染更具有优势.由于CUDA中的 ...
- CUDA和OpenGL互操作经典博文赏析和学习
1.使用cuda+opengl图形互操作性实现MPR.原学位论文学习:实时交互的医学图像可视化.在该论文的第5.1.1节. 2.cuda与opengl互操作之PBO 3.cuda与opengl互操作之 ...
- CUDA 与 OpenGL 的互操作
CUDA 与 OpenGL 的互操作一般是使用CUDA生成数据,然后在OpenGL中渲染数据对应的图形.这两者的结合有两种方式: 1.使用OpenGL中的PBO(像素缓冲区对象).CUDA生成像素数据 ...
- OpenGL完整实例
结合上一节的内容,分享完整代码. 先画一个cube,然后通过OnGestureListener去触发onFling使它旋转起来. OnGestureListener相关的方法我已经都加了注释,可以参考 ...
- cuda+ffmpeg+opengl解码rtsp h264码流多路
Cuda 解码 全尺寸 解码 .全尺寸窗口绘制测试( 分别 测试 视频 文件和 IP 相机 实时视频 ) 1080 p 视屏 文件 全尺寸 解码 全尺寸 显示 72 0p IP 相机 全尺寸 解码 全 ...
- CUDA编程
目录: 1.什么是CUDA 2.为什么要用到CUDA 3.CUDA环境搭建 4.第一个CUDA程序 5. CUDA编程 5.1. 基本概念 5.2. 线程层次结构 5.3. 存储器层次结构 5.4. ...
- OpenGL与CUDA互操作方式总结
一.介绍 CUDA是Nvidia推出的一个通用GPU计算平台,对于提升并行任务的效率非常有帮助.本人主管的项目中采用了OpenGL做图像渲染,但是在数据处理方面比较慢,导致帧率一直上不来.于是就尝试把 ...
- [转]OpenGL与CUDA互操作方式总结
一.介绍 CUDA是Nvidia推出的一个通用GPU计算平台,对于提升并行任务的效率非常有帮助.本人主管的项目中采用了OpenGL做图像渲染,但是在数据处理方面比较慢,导致帧率一直上不来.于是就尝试把 ...
随机推荐
- 关于responseHeader的一些基础设置
1.关于响应头的一些基础设置 //设置相应头 response.addHeader("name","zhangsan"); response.addIntHea ...
- docker 安装ElasticSearch的中文分词器IK
首先确保ElasticSearch镜像已经启动 安装插件 方式一:在线安装 进入容器 docker exec -it elasticsearch /bin/bash 在线下载并安装 ./bin/ela ...
- UVA1339(字母映射)
memcmp(const void *buf1, const void *buf2, unsigned int count)可以比较两个串相等 http://baike.baidu.com/link? ...
- SQL2008使用with求余额表,流水账方式
1.先准备数据,将要求余额的表数据插入临时表 SELECT Serial, VoucherNum, SubjectNum, SubjectName, Direction, Amount INTO #T ...
- js数组与字符串处理 slice、splice、substring、substr、push、pop、shift、reverse、sort、join、split
数组 方法 1.在数组末尾添加.删除元素 push()方法可以接收任意数量的参数,把它们逐个添加到数组的末尾,并返回修改后数组的长度.改变原数组 pop()方法则从数组末尾移除最后一个元素,减少数组的 ...
- npm安装指定版本
今天犯了一个低级错误,在npm安装依赖时,命令写成下了格式 npm i --save iview 2.0.0 要安装指定版本应该使用 npm i --save iview@2.0.0 谨记
- Spark企业级应用开发和调优
1.Spark企业级应用开发和调优 Spark项目编程优化历程记录,主要介绍了Spark企业级别的开发过程中面临的问题和调优方法.包含合理分配分片,避免计算中间结果(大数据量)的collect,合理使 ...
- 【 Oral English】Pronunciation
一.英语音素 1.元音(元首,主要部分) 特点: a.无阻碍,拖很长认可辨别 b.声音响亮 2.辅音(重点,刻意练习) 特点: a.刻意阻碍 b.短促 二.汉语元素 1.音节:最小组成成分,而非元/辅 ...
- 任务十三:零基础JavaScript编码(一)
任务目的 JavaScript初体验 初步明白JavaScript的简单基本语法,如变量.函数 初步了解JavaScript的事件是什么 初步了解JavaScript中的DOM是什么 任务描述 参考以 ...
- Ubuntu 中QT 用sogou拼音 安装
1.下载搜狗输入法的安装包 下载地址为:http://pinyin.sogou.com/linux/ ,如下图,要选择与自己系统位数一致的安装包,我的系统是64位,所以我下载64位的安装包 2.按键C ...