PBO(像素缓冲区对象)也可以映射到CUDA地址空间,CUDA的kernel函数可以讲计算结果直接写到PBO中,然后将 PBO的内容复制到texture,进行绘制。
具体使用步骤:
1、创建PBO
// Generate a buffer ID called a PBO (Pixel Buffer Object)
glGenBuffers(1,pbo);
// Make this the current UNPACK buffer (OpenGL is state-based)
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, *pbo);
// Allocate data for the buffer. 4-channel 8-bit image
glBufferData(GL_PIXEL_UNPACK_BUFFER, size_tex_data, NULL, GL_DYNAMIC_COPY);
2、注册PBO
struct cudaGraphicsResource *cuda_pbo_resource;
cudaGraphicsGLRegisterBuffer(&cuda_pbo_resource, *pbo, cudaGraphicsMapFlagsWriteDiscard);
3、映射PBO
cudaGraphicsMapResources(1, &cuda_pbo_resource, 0);
cudaGraphicsResourceGetMappedPointer((void**)&d_output, &num_bytes, cuda_pbo_resource);
launch_kernel(d_output, window_width, window_height, w);
5、解除映射
cudaGraphicsUnmapResources(1, &cuda_pbo_resource, 0);
6、解除注册
cudaGraphicsUnregisterResource(cuda_pbo_resource);
7、删除PBO
glBindBuffer(GL_ARRAY_BUFFER, *pbo);
glDeleteBuffers(1, pbo);
8、绘制
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo);
glBindTexture(GL_TEXTURE_2D, textureID);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 128, 128,/*window_width, window_height,*/
GL_RGBA, GL_UNSIGNED_BYTE, NULL);
glBegin(GL_QUADS);
glTexCoord2f(0.0f,1.0f); glVertex3f(0.0f,0.0f,0.0f);
glTexCoord2f(0.0f,0.0f); glVertex3f(0.0f,1.0f,0.0f);
glTexCoord2f(1.0f,0.0f); glVertex3f(1.0f,1.0f,0.0f);
glTexCoord2f(1.0f,1.0f); glVertex3f(1.0f,0.0f,0.0f);
glEnd();
代码:
//myPBO.cpp
#include <gl/glew.h>
#include <cuda_runtime.h>
#include <cutil_inline.h>
#include <cutil_gl_inline.h>
#include <cutil_gl_error.h>
#include <rendercheck_gl.h>
#include <sdkHelper.h>
extern void initCuda(int argc, char **argv);
extern void runCuda();
unsigned int window_width = 500;
unsigned int window_height = 500;
unsigned int image_width = 128;//window_width;
unsigned int image_height = 128;//window_height;
unsigned int timer = 0;
int animFlag = 1;
float animTime = 0.0f;
float animInc = 0.1f;
GLuint pbo = NULL;
GLuint textureID = NULL;
struct cudaGraphicsResource *cuda_pbo_resource;
extern "C" void launch_kernel(uchar4* , unsigned int, unsigned int, float);
void createPBO(GLuint *pbo)
{
if (pbo)
{
int num_texels = image_width * image_height;
int num_values = num_texels * 4