CUDA 与 OpenGL 的互操作
2019-09-17 09:56:39来源:博客园 阅读 ()
CUDA 与 OpenGL 的互操作
CUDA 与 OpenGL 的互操作一般是使用CUDA生成数据,然后在OpenGL中渲染数据对应的图形。这两者的结合有两种方式:
1、使用OpenGL中的PBO(像素缓冲区对象)。CUDA生成像素数据,OpenGL直接渲染即可。
2、使用OpenGL中的FBO(顶点缓冲区对象)。CUDA生成顶点数据,OpenGL渲染。
这两种方法的核心都是将OpenGL中的缓冲区对象映射到CUDA内存空间中(让CUDA的内存指针指向OpenGL的缓冲区),这样就不需要将缓冲区中的数据传输至CUDA内存中,然后利用CUDA的高并行计算性能加速计算,最后直接使用OpenGL渲染。
一个例子,使用CUDA根据时间动态生成16个点,在屏幕上显示。
步骤:
1、设置与OpenGL互操作的设备
status=cudaGLSetGLDevice(0);
2、在CUDA中注册缓冲区对象
status = cudaGLRegisterBufferObject(this->VBO);
3、映射缓冲区对象:让CUDA内存指针指向缓冲区对象对应的空间
// 映射缓冲对象 float4* position; status=cudaGLMapBufferObject((void**)&position, this->VBO);
4、运行核函数
// 运行核函数 dim3 dimBlock(4, 4, 1); dim3 dimGrid(1); KernelFunc<<<dimGrid, dimBlock>>>(position, clock(), 4, 4); cudaThreadSynchronize(); //同步线程
5、取消映射
status=cudaGLUnmapBufferObject(this->VBO);
效果图:
注意:当CUDA的kernel函数修改CUDA指针指向的空间超出OpenGL缓冲对象大小时,会导致后面出现取消映射失败。(这里所说的CUDA指针是映射到OpenGL缓冲对象的)
完整代码如下:
#include "GenVertex.cuh" #include <time.h> __global__ void KernelFunc(float4* position, float time, unsigned int width, unsigned int height) { unsigned int x = blockIdx.x*blockDim.x + threadIdx.x; unsigned int y = blockIdx.y*blockDim.y + threadIdx.y; float u = x / (float)width; float v = y / (float)height; u = u*2.0f - 1.0f; v = v*2.0f - 1.0f; float freq = 4.0f; float w = sinf(u*freq + time*0.001f)*cosf(v*freq + time*0.001f)*0.5f; position[y*width + x] = make_float4(u*10, w*10, v*10, 1.0f); } GenVertex::GenVertex() { this->setup(); } GenVertex::~GenVertex() { } void GenVertex::setup() { cudaError_t status; //设备设置 status=cudaGLSetGLDevice(0); if (status != cudaSuccess) { puts("setup Device failed!"); } } void GenVertex::setVBO(unsigned int vbo) { this->VBO = vbo; cudaError_t status; status = cudaGLRegisterBufferObject(this->VBO); if (status != cudaSuccess) { puts("Register buffer object failed!"); } } void GenVertex::createVtxWithCuda() { cudaError_t status; // 映射缓冲对象 float4* position; status=cudaGLMapBufferObject((void**)&position, this->VBO); if (status != cudaSuccess) { puts("map buffer object failed!"); } // 运行核函数 dim3 dimBlock(4, 4, 1); dim3 dimGrid(1); KernelFunc<<<dimGrid, dimBlock>>>(position, clock(), 4, 4); cudaThreadSynchronize(); //同步线程 status=cudaGLUnmapBufferObject(this->VBO); if (status != cudaSuccess) { puts("unmap buffer object failed!"); } }
原文链接:https://www.cnblogs.com/chen9510/p/11530567.html
如有疑问请与原作者联系
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
上一篇:对象的构造与析构(一)
下一篇:C++ --const修饰指针
- 第七章 1.输入输出与模板 2020-04-04
- 数据结构-线性表 2020-03-28
- 二叉树(1)二叉树基本操作通用接口 2020-02-06
- 向量容器vector操作 2020-02-03
- c++-字符串和时间操作 2019-12-24
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash