首页 > 学院 > 开发设计 > 正文

CUDA+OpenGL混合编程

2019-11-11 01:18:46
字体:
来源:转载
供稿:网友

CUDA+OpenGL混合编程示例:

#include <stdio.h>    #include <stdlib.h>   #include "GL/glew.h"    #include "GL/glut.h"    #include <cuda_runtime.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;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 = 255 * sinf(x*y);	unsigned char red = 255 * cosf(offset*offset);	unsigned char blue = 255 * cosf(offset*x*y);	ptr[offset].x = red;	ptr[offset].y = green;	ptr[offset].z = blue;	ptr[offset].w = 255;}void drawFunc(void){	glDrawPixels(DIM, DIM, GL_RGBA, GL_UNSIGNED_BYTE, 0);	glutSwapBuffers();}static void keyFunc(unsigned char key, int x, int y){	switch (key) {	case 27:		cudaGraphicsUnregisterResource(resource);		glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, 0);		glDeleteBuffers(1, &bufferObj);		exit(0);	}}int main(int argc, char* argv[]){	// 定义一个设备属性对象prop  	cudaDeviceProp prop;	int dev;	memset(&prop, 0, sizeof(cudaDeviceProp));	//限定设备计算功能集的版本号  	prop.major = 1;	prop.minor = 0;	//选择在计算功能集的版本号为1.0的GPU设备上运行  	cudaChooseDevice(&dev, &prop);	//选定GL程序运行的设备  	cudaGLSetGLDevice(dev);	//OpenGL环境初始化  	glutInit(&argc, argv);	glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA);	glutInitWindowSize(DIM, DIM);	glutCreateWindow("CUDA+OpenGL");	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(1, &bufferObj);	glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, bufferObj);	glBufferData(GL_PIXEL_UNPACK_BUFFER_ARB, DIM*DIM * 4, NULL, GL_DYNAMIC_DRAW_ARB);	cudaGraphicsGLRegisterBuffer(&resource, bufferObj, cudaGraphicsMapFlagsNone);	uchar4* devPtr;	size_t size;	cudaGraphicsMapResources(1, &resource, NULL);	cudaGraphicsResourceGetMappedPointer((void**)&devPtr, &size, resource);	dim3 grids(DIM / 16, DIM / 16);	dim3 threads(16, 16);	cudaGLKernel << <grids, threads >> > (devPtr);	cudaGraphicsUnmapResources(1, &resource, NULL);	glutKeyboardFunc(keyFunc);	glutDisplayFunc(drawFunc);	glutMainLoop();	return 0;}

在GPU上根据线程索引的正余弦函数生成数据,并把这些数据绑定到OpenGL声明的一个顶点缓冲对象VBO(VBO其实就是显存上的一个存储区域,可以保持大量的顶点属性信息)上,再由OpenGL根据该VBO数据把图像绘制出来,运行效果:


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表