CUDAExample: 波纹示例

需要用到的已经封装好的辅助类: CPUAnimBitmap

定义个grid 和 block 的维度都是二维的

#include"cpu_anim.h"
#include "cuda_runtime.h"
#include <device_launch_parameters.h>

#define DIM 512
static void CheckCudaErrorAux(const char*, unsigned, const char*, cudaError_t);
#define CUDA_CHECK_RETURN(value) CheckCudaErrorAux(__FILE__,__LINE__, #value, value)


struct DataBlock 
{
	unsigned char* dev_bitmap;
	CPUAnimBitmap* bitmap;	
};

void cleanup(DataBlock *d) 
{
	cudaFree(d->dev_bitmap);
}

// 第一个指针来指向北村输出像素值的设备内存,是一个全局变量
// ticks 表示当前的动画时间
__global__ void kernel(unsigned char * imageptr, int ticks)
{
	// 每个线程都得到它在线程块中的索引,以及这个线程块在线程格中的索引
	// 并将这两个值转换为图形中的唯一索引(x,y)
	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 - DIM / 2;
	float fy = y - DIM / 2;
	float d = sqrtf(fx * fx + fy * fy);

	unsigned char grey = (unsigned char)(128.0f + 127.0f * cos(d / 10.0f - ticks / 7.0f) / (d / 10.0f + 1.0f));

	imageptr[offset * 4 + 0] = grey;
	imageptr[offset * 4 + 1] = 0;
	imageptr[offset * 4 + 2] = 255 - grey;
	imageptr[offset * 4 + 3] = 255;

}

// 根据时间戳ticks生成新的图像
void generate_frame(DataBlock *d, int ticks) 
{
	// 线程格中包含的并行线程块的数量
	dim3 blocks(DIM / 16, DIM / 16);
	// 每个线程块中包含的线程数量
	dim3 threads(16, 16);
	kernel <<<blocks, threads>>> (d->dev_bitmap, ticks);
	CUDA_CHECK_RETURN(cudaMemcpy(d->bitmap->get_ptr(),
		d->dev_bitmap,
		d->bitmap->image_size(),
		cudaMemcpyDeviceToHost));
}


int main(void)
{
	DataBlock data;
	CPUAnimBitmap	bitmap(DIM, DIM, &data);
	data.bitmap = &bitmap;
	std::cout << "image size : " << data.bitmap->image_size() << std::endl;
	CUDA_CHECK_RETURN(cudaMalloc((void**)&data.dev_bitmap, bitmap.image_size()));
	// 将指向generate_frame()的函数指针传递给anim_and_exit()
	// 每当要生生成一帧新的动画都会调用generate_frame()
	bitmap.anim_and_exit((void(*)(void *,int))generate_frame, (void(*)(void*))cleanup);

	return 0;
}

static void CheckCudaErrorAux(const char* file, unsigned line, const char* statement, cudaError_t err)
{
	if (err == cudaSuccess)
		return;
	std::cerr << statement << " returned " << cudaGetErrorString(err) << "(" << err << ") at " << file << ":" << line << std::endl;
	exit(1);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值