本文要解决的问题是如何实现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

CUDA与OpenGL互操作实例的更多相关文章

  1. [转]CUDA和OpenGL互操作的实现及分析

    CUDA和OpenGL互操作的实现及分析刘进锋.郭雷(西北工业大学 自动化学院,陕西西安710129) 1 CUDA与OpenGL概述 OpenGL是图形硬件的软件接口,它是在SGI等多家世界著名的计 ...

  2. CUDA与OpenGL互操作

    当处理较大数据量的时候,往往会用GPU进行运算,比如OpenGL或者CUDA.在实际的操作中,往往CUDA实现并行计算会比OpenGL更加方便,而OpenGL在进行后期渲染更具有优势.由于CUDA中的 ...

  3. CUDA和OpenGL互操作经典博文赏析和学习

    1.使用cuda+opengl图形互操作性实现MPR.原学位论文学习:实时交互的医学图像可视化.在该论文的第5.1.1节. 2.cuda与opengl互操作之PBO 3.cuda与opengl互操作之 ...

  4. CUDA 与 OpenGL 的互操作

    CUDA 与 OpenGL 的互操作一般是使用CUDA生成数据,然后在OpenGL中渲染数据对应的图形.这两者的结合有两种方式: 1.使用OpenGL中的PBO(像素缓冲区对象).CUDA生成像素数据 ...

  5. OpenGL完整实例

    结合上一节的内容,分享完整代码. 先画一个cube,然后通过OnGestureListener去触发onFling使它旋转起来. OnGestureListener相关的方法我已经都加了注释,可以参考 ...

  6. cuda+ffmpeg+opengl解码rtsp h264码流多路

    Cuda 解码 全尺寸 解码 .全尺寸窗口绘制测试( 分别 测试 视频 文件和 IP 相机 实时视频 ) 1080 p 视屏 文件 全尺寸 解码 全尺寸 显示 72 0p IP 相机 全尺寸 解码 全 ...

  7. CUDA编程

    目录: 1.什么是CUDA 2.为什么要用到CUDA 3.CUDA环境搭建 4.第一个CUDA程序 5. CUDA编程 5.1. 基本概念 5.2. 线程层次结构 5.3. 存储器层次结构 5.4. ...

  8. OpenGL与CUDA互操作方式总结

    一.介绍 CUDA是Nvidia推出的一个通用GPU计算平台,对于提升并行任务的效率非常有帮助.本人主管的项目中采用了OpenGL做图像渲染,但是在数据处理方面比较慢,导致帧率一直上不来.于是就尝试把 ...

  9. [转]OpenGL与CUDA互操作方式总结

    一.介绍 CUDA是Nvidia推出的一个通用GPU计算平台,对于提升并行任务的效率非常有帮助.本人主管的项目中采用了OpenGL做图像渲染,但是在数据处理方面比较慢,导致帧率一直上不来.于是就尝试把 ...

随机推荐

  1. 【转】.net MVC 生命周期

    对于Asp.net MVC,我对它的生命周期还是兴趣很浓,于是提出两个问题: 一个HTTP请求从IIS移交到Asp.net运行时,Asp.net MVC是在什么时机获得了控制权并对请求进行处理呢?处理 ...

  2. Filter---javaweb的过滤器

    1.Filter是什么? Filter的基本功能是对Servlet容器调用Servlet的过程进行拦截,从而在Servlet进行响应处理的前后实现一些特殊的功能. 在Servlet API中定义了三个 ...

  3. 基于Node.js的ghost开源博客平台

    Ghost 是一套基于Node.js 构建的开源博客平台(Open source blogging platform),具有易用的书写界面和体验. 1.安装node windows 下安装npm:ht ...

  4. 小任务之使用SVG画柱状图~

    function drawBar(data) { var barGraph = document.querySelector("#bar-graph"); var graphWid ...

  5. 谈谈我从工作中理解的CDN

    一.CDN定义 CDN的全称是Content Delivery Network,即内容分发网络.其基本思路是尽可能避开互联网上有可能影响数据传输速度和稳定性的瓶颈和环节,使内容传输的更快.更稳定.通过 ...

  6. es6 import笔记

    export输出: // profile.js var firstName = 'Michael'; var lastName = 'Jackson'; var year = 1958; export ...

  7. 记录开发Nodejs c++ addon的一些经验(二、数据类型的转换(尤其是Buffer))

    常见的数据类型的转换基本比较容易,结合nan应该不是一件难事 参考链接: http://blog.jobbole.com/109598/ http://deadhorse.me/nodejs/2012 ...

  8. Python基础-面向过程编程实现Linux下cat -rl ‘dir’ |grep ‘keywords’ 功能

    函数是Python内建支持的一种封装,我们通过把大段代码拆成函数,通过一层一层的函数调用,就可以把复杂任务分解成简单的任务,这种分解可以称之为面向过程的程序设计.函数就是面向过程的程序设计的基本单元. ...

  9. 【One Day菜鸟到大鸟】MyBatis搭建环境

    一.概述     MyBatis是一个持久化框架和Hiberante差不多.比起JDBC来说MyBatis封装了JDBC让我们能够面向对象开发.比起Hiberante来说卸下了Hiberante那种重 ...

  10. Codeforces Round #413 B. T-shirt buying

    B. T-shirt buying time limit per test   3 seconds memory limit per test   256 megabytes   A new pack ...