专栏名称: Cocoa开发者社区
CocoaChina苹果开发中文社区官方微信,提供教程资源、app推广营销、招聘、外包及培训信息、各类沙龙交流活动以及更多开发者服务。
目录
相关文章推荐
51好读  ›  专栏  ›  Cocoa开发者社区

iOS GPGPU 编程:GPU进行浮点计算并读取结果

Cocoa开发者社区  · 公众号  · ios  · 2016-08-31 08:05

正文

请到「今天看啥」查看全文



3、配置program。注意不要马上链接program。


GLuint vertShader, fragShader;

NSString *vertShaderPathname, *fragShaderPathname;

// Create shader program.

_program = glCreateProgram();

// Create and compile vertex shader.

vertShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"vsh"];

if (![self compileShader:&vertShader type:GL_VERTEX_SHADER file:vertShaderPathname]) {

NSLog(@"Failed to compile vertex shader");

return NO;

}

// Create and compile fragment shader.

fragShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"fsh"];

if (![self compileShader:&fragShader type:GL_FRAGMENT_SHADER file:fragShaderPathname]) {

NSLog(@"Failed to compile fragment shader");

return NO;

}

// Attach vertex shader to program.

glAttachShader(_program, vertShader);

// Attach fragment shader to program.

glAttachShader(_program, fragShader);


4、在链接program前配置transform feedback输出属性名。


仔细观察,本文使用的Vertex Shader与正常绘图所用的着色器略有区别:没输出顶点坐标给Fragment Shader使用。因此,需要glTransformFeedbackVaryings告诉ES欲捕获到输出缓冲区的属性属性。


GLchar *varyings[] = {"outValue"};

glTransformFeedbackVaryings(_program, sizeof(varyings) / sizeof(varyings[0]), varyings, GL_INTERLEAVED_ATTRIBS);


glTransformFeedbackVaryings需要输出变量的数量及名称,在varyings数组指定Vertex Shader将输出的属性名。


  • GL_INTERLEAVED_ATTRIBS指定输出属性数值交错写入一个缓冲区。交错数据需要指定读写跨距(stride)。

  • GL_SEPARATE_ATTRIBS为输出属性指定多个目标缓冲区,一对一写入或不同偏移写入到一个缓冲区。


5、链接program。链接操作包含检查链接状态(glLinkProgram),查找编译错误,在调试模式下还可验证当前ES状态是否可执行program中的程序(glValidateProgram),即找出其中运行时错误,根据校验情况,输出错误信息。glValidateProgram操作消耗资源较多,Release模式下通常不调用此函数。示例如下。


// 1、检查链接状态

glLinkProgram(_program);

GLint linkStatus = GL_FALSE;

glGetProgramiv(_program, GL_LINK_STATUS, &linkStatus);if (linkStatus == GL_FALSE) {

GLint logLength = 0;

glGetProgramiv(_program, GL_INFO_LOG_LENGTH, &logLength);    if (logLength > 0) {

GLchar *logBuffer = calloc(1, logLength);

glGetProgramInfoLog(_program, logLength, NULL, logBuffer);        printf("%s", logBuffer);

free(logBuffer);

}

}

// 2、验证Shader是否可执行

glValidateProgram(_program);

glGetProgramiv(_program, GL_INFO_LOG_LENGTH, &logLength);if (logLength > 0) {

GLchar *log = (GLchar *)malloc(logLength);

glGetProgramInfoLog(_program, logLength, &logLength, log);

NSLog(@"Program validate log:\n%s", log);

free(log);

}

glGetProgramiv(_program, GL_VALIDATE_STATUS, &status);if (status == 0) {    return NO;

}return YES;


6、配置GPU的输入数据缓冲区。 这里需要注意,若直接上传数据,则不能映射上传缓冲区到主存去查看上传的数据。用缓冲区(Vertex Buffer Object)则正常。


使用VBO前,可以配置VAO,不配置也不影响运行结果。


GLuint vao;

glGenVertexArrays(1, &vao);

glBindVertexArray(vao);


上传数据方式A、直接上传数据至GPU的实现,yourData为数组。


GLfloat yourData[] = {2, 3, 4, 5, 6};







请到「今天看啥」查看全文


推荐文章
史事挖掘机  ·  [老照片]上海1948,蒋经国铁腕打虎!
8 年前
酱子工厂  ·  寡妇征婚,不笑我嫁给你!
7 年前
十点读书  ·  终于, 我们都活成了薛宝钗
7 年前