注册 登录
主题 : 利用OpenCL生成球体顶点
级别: 天使

状态: 连续签到 - [7天]
UID: 5513
精华: 19
发帖: 90659
可可豆: 922081 CB
威望: 921946 点
在线时间: 5508(时)
注册时间: 2009-05-06
最后登录: 2019-09-16
0 楼:  发表于: 2010-10-21 05:47    发自: Web Page
来源于 Mac类代码 分类

利用OpenCL生成球体顶点    (在iOS代码库中浏览本帖)

现在Apple Special Event October 20, 2010已经完全加载好了。这篇文章写好后立马观看,哈哈哈……
之前,我发过一份代码是关于如何用OpenGL生成一个球体,请参考以下链接:

http://www.cocoachina.com/bbs/read.php?tid-33172.html


这边,我将列出如何利用OpenCL来生成与上面程序对应的球体顶点坐标。
我先列出原来OpenGL中的计算方式:


    vertices = (GLfloat*)malloc(91 * 360 * 4 * sizeof(*vertices));
    double xy_theta = 0.0, xz_theta = 0.0;
    const double radius = 0.5;
    int innerCount = 0;
    for(int i = 0; i < 360 * 91 * 4; i += 4)
    {
        double r_xy = xy_theta * M_PI / 180.0;
        double r_xz = xz_theta * M_PI / 180.0;
        double x = radius * cos(r_xy) * cos(r_xz);
        double y = radius * sin(r_xy);
        double z = -radius * cos(r_xy) * sin(r_xz);

        xy_theta += 1.0;
        innerCount++;
        if(innerCount == 91)
        {
            innerCount =
0;
            xy_theta =
0.0;
            xz_theta +=
1.0;
        }

vertices[ i ] = (GLfloat)x;
       
vertices[i + 1] = (GLfloat)y;
        vertices[i + 2] = (GLfloat)z;
       
vertices[i + 3] = 1.0f;
    }




首先,从对顶点的分配上我们可以看出,半球体的顶点可以被组织成一个二维数组——vertices[360][91 * 4]。
而对每个顶点坐标的计算的算法都是一致的,因此可以完全可以利用具有data parallel特征的GPU对此进行计算。
下面我们主要的问题还是确定工作项和工作组的划分。
由于360 * 91的分法有很多,但都无法划分成能达到用满512个工作项的分法。因此,我这里对工作项的个数进行扩充——
对于一个工作组,16 * 32正好等于512;那么我们可以通过计算获得不小于360能被16整除最小的整数是368,不小于91的能倍32整除的数是96,因此我们可以将工作项设置为368 * 96。而我们在内核计算时,只要判断获得的维度在指定范围内就OK了。
下面给出内核代码:

__kernel void SphereVerticesGenerate(
                   
__global float output[360][91 * 4]
                    )
{
   
int dimX = get_global_id(0);
   
int dimY = get_global_id(1);
   
if(dimX < 360 && dimY < 91)
    {
       
const float radius = 0.5f;
       
float xy_theta = (float)dimY;
       
float xz_theta = (float)dimX;
       
float r_xy = xy_theta / 180.0f;
       
float r_xz = xz_theta / 180.0f;
       
float x = radius * cospi(r_xy) * cospi(r_xz);
       
float y = radius * sinpi(r_xy);
       
float z = -radius * cospi(r_xy) * sinpi(r_xz);

        output[dimX][dimY *  
4] = (float)x;
        output[dimX][dimY *
4 + 1] = (float)y;
        output[dimX][dimY *
4 + 2] = (float)z;
        output[dimX][dimY *
4 + 3] = 1.0f;
    }
}


上述代码就是OpenCL的内核函数。我们可以看到,通过对dimX和dimY的过滤可以排除对我们计算范围外的元素。
而OpenCL的内建函数sinpi、cospi的语义是:sin(π * rand)、cos(π * rand),这样,我们不需要自己再指定π了,呵呵。
在附赠的工程代码中,内核函数在Shaders目录下的kernel.cl文件中。而MyView.m中的
- (void)prepareOpenGL
方法中,我用了预编译来选择使用CPU计算还是GPU计算顶点坐标。

[ 此帖被zenny_chen在2010-11-11 10:10重新编辑 ]

附件: OpenCL_sphere.zip (36 K) 下载次数:187
新浪围脖地址:http://t.sina.com.cn/1181389417
CPU Dasher for OS X: https://itunes.apple.com/cn/app/cpu-dasher/id1013487510?mt=12

级别: 天使

状态: 连续签到 - [7天]
UID: 5513
精华: 19
发帖: 90659
可可豆: 922081 CB
威望: 921946 点
在线时间: 5508(时)
注册时间: 2009-05-06
最后登录: 2019-09-16
1 楼:  发表于: 2010-10-21 15:21    发自: Web Page
话说上面的斜体字咋不能改正?
谁帮偶改改?
新浪围脖地址:http://t.sina.com.cn/1181389417
CPU Dasher for OS X: https://itunes.apple.com/cn/app/cpu-dasher/id1013487510?mt=12

级别: 天使

状态: 连续签到 - [7天]
UID: 5513
精华: 19
发帖: 90659
可可豆: 922081 CB
威望: 921946 点
在线时间: 5508(时)
注册时间: 2009-05-06
最后登录: 2019-09-16
2 楼:  发表于: 2010-11-11 10:11    发自: Web Page
哦,字体改好了。终于知道为何会出现斜体字。因为——[ i ](方括号与i之间没有空格的话就会变成斜体),呵呵。
所以以后贴代码时各位必须注意一下,把它写成[ i ]就米有问题了……



新浪围脖地址:http://t.sina.com.cn/1181389417
CPU Dasher for OS X: https://itunes.apple.com/cn/app/cpu-dasher/id1013487510?mt=12

CocoaChina社区转载内容已尽可能注明出处,如未能核实来源或转发内容图片有权利瑕疵的,请及时联系社区进行修改或删除【联系方式QQ : 3442093904 邮箱:support@cocoachina.com】文章内容为作者独立观点,不代表CocoaChina社区立场。版权归原作者所有,如申请授权请联系作者,因文章侵权CocoaChina社区不承担任何法律及连带责任。

描述
快速回复

关注本帖(如果有新回复会站内信通知您)

发帖、回帖都会得到可观的积分奖励。查看论坛积分规则

按"Ctrl+Enter"直接提交
    顶部