国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統 > iOS > 正文

iOS之OpenGL ES【2】:渲染管線和著色器

2019-11-06 09:54:00
字體:
來源:轉載
供稿:網友

OpenGL ES的著色器主要有片元著色器和頂點著色器,其使用方法簡單的介紹如下:

創建,裝載和編譯 shader

繼續上一篇的基礎上,在工程中新建一個類,命名為OpenGLESUtils(繼承于NSObject),在.h中聲明2個方法: + (GLuint)loadShader:(GLenum)type shaderString:(NSString *)shaderString; + (GLuint)loadShader:(GLenum)type shaderFilePath:(NSString *)filePath;在OpenGLESUtils.m實現上面的兩個方法:+(GLuint)loadShader:(GLenum)type shaderFilePath:(NSString *)filePath { NSError *error; NSString *shaderString = [NSString stringWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:&error]; if (!shaderString) { NSLog(@"Error: loading shader file: %@ %@", filePath, error.localizedDescription); return 0; } else { return [self loadShader:type shaderString:shaderString]; }} + (GLuint)loadShader:(GLenum)type shaderString:(NSString *)shaderString { GLuint shader = glCreateShader(type); if (shader == 0) { NSLog(@"Error: failed to create shader."); return 0; } const char *shaderStringUTF8 = [shaderString UTF8String]; glShaderSource(shader, 1, &shaderStringUTF8, NULL); glCompileShader(shader); GLint compiled = 0; glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled); if (!compiled) { GLint inforLen = 0; glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &inforLen); if (inforLen > 1) { char *infoLog = malloc(sizeof(char)*inforLen); glGetShaderInfoLog(shader, inforLen, NULL, infoLog); free(infoLog); } glDeleteShader(shader); return 0; } return shader;}OpenGLESUtils中的兩個方法用來跟進shader腳本字符串和shader腳本文件創建,具體方法如下: 1、創建/刪除 shader:函數 glCreateShader 用來創建 shader,參數 GLenum type 表示我們要處理的 shader 類型,它可以是 GL_VERTEX_SHADER 或 GL_FRAGMENT_SHADER,分別表示頂點 shader 或 片元 shader。它返回一個句柄指向創建好的 shader 對象; 2、裝載 shader:函數 glShaderSource 用來給指定 shader 提供 shader 源碼。第一個參數是 shader 對象的句柄;第二個參數表示 shader 源碼字符串的個數;第三個參數是 shader 源碼字符串數組;第四個參數一個 int 數組,表示每個源碼字符串應該取用的長度,如果該參數為 NULL,表示假定源碼字符串是 /0 結尾的,讀取該字符串的內容指定 /0 為止作為源碼,如果該參數不是 NULL,則讀取每個源碼字符串中前 length(與每個字符串對應的 length)長度個字符作為源碼; 3、編譯 shader:函數 glCompileShader 用來編譯指定的 shader 對象,這將編譯存儲在 shader 對象中的源碼。我們可以通過函數 glGetShaderiv 來查詢 shader 對象的信息,如本例中查詢編譯情況,此外還可以查詢 GL_DELETE_STATUS,GL_INFO_LOG_STATUS,GL_SHADER_SOURCE_LENGTH 和 GL_SHADER_TYPE。在這里我們查詢編譯情況,如果返回 0,表示編譯出錯了,錯誤信息會寫入 info 日志中,我們可以查詢該 info 日志,從而獲得錯誤信息。

編寫著色腳本

添加頂點著色腳本:在工程中新建一個Empty,命名為VertexShader.glsl,實現內容如下:attribute vec4 vPosition;void main(void) { gl_Position = vPosition;}添加片元著色腳本:同理實現,代碼如下:PRecision mediump float;void main() { gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);}創建 program,裝配 shader,鏈接 program,使用 program: 1、在 OpenGLView.h 的 OpenGLView 類聲明中添加兩個成員: GLuint programHandle; GLuint positionSlot; 2、然后依然在 OpenGLView.m 中的category 中添加成員方法: - (void)setupProgram { NSString *vertexShaderPath = [[NSBundle mainBundle] pathForResource:@"VertexShader" ofType:@"glsl"]; NSString *fragmentShaderPath = [[NSBundle mainBundle] pathForResource:@"FragmentShader" ofType:@"glsl"]; GLuint vertexShader = [OpenGLESUtils loadShader:GL_VERTEX_SHADER shaderFilePath:vertexShaderPath]; GLuint fragmentShader =[OpenGLESUtils loadShader:GL_FRAGMENT_SHADER shaderFilePath:fragmentShaderPath]; programHandle = glCreateProgram(); if (!programHandle) { NSLog(@"Failed to create program."); return; } glAttachShader(programHandle, vertexShader); glAttachShader(programHandle, fragmentShader); glLinkProgram(programHandle); GLint linked; glGetProgramiv(programHandle, GL_LINK_STATUS, &linked); if (!linked) { GLint infoLen = 0;glGetProgramiv(programHandle, GL_INFO_LOG_LENGTH, &infoLen); if (infoLen > 1) { char *infoLog = malloc(sizeof(char) *infoLen); glGetShaderInfoLog(programHandle, infoLen, NULL, infoLog); NSLog(@"Error linking program:/n%s/n", infoLog ); free(infoLog); } glDeleteProgram(programHandle); programHandle = 0; return; } glUseProgram(programHandle); positionSlot = glGetAttribLocation(programHandle, "vPosition");}使用實例: 在 - (void)layoutSubviews中調用 render 方法之前,插入對 setupProgram 的調用:- (void)layoutSubviews { [self setupLayer]; [self setupContext]; [self destoryRenderAndFrameBuffer]; [self setupRenderBuffer]; [self setupFrameBuffer]; [self setupProgram]; [self render];}// 改寫render方法:- (void)render { // 設置清屏顏色 glClearColor(0.0, 0.0, 1.0, 1.0); // 用來指定要用清屏顏色來清除由mask指定的buffer,此處是color buffer glClear(GL_COLOR_BUFFER_BIT); // 渲染區域 glViewport(0, 0, self.frame.size.width, self.frame.size.height); GLfloat vertices[] = { 0.0f, 0.5f, 0.0f, -0.5f, -0.5f, 0.0f, 0.5f, -0.5f, 0.0f }; // 通過 glVertexAttribPointer 將三角形頂點數據裝載到 OpenGL ES 中并與 vPositon 關聯起來 glVertexAttribPointer(positionSlot, 3, GL_FLOAT, GL_FALSE, 0, vertices); glEnableVertexAttribArray(positionSlot); // glDrawArrays 將三角形圖元渲染出來 glDrawArrays(GL_TRIANGLES, 0, 3); [eaglContext presentRenderbuffer:GL_RENDERBUFFER ];}

參考文章:http://blog.csdn.net/kesalin/article/details/8223649


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 安丘市| 太白县| 武义县| 汉川市| 库车县| 阿拉善右旗| 比如县| 兴业县| 龙海市| 明星| 余姚市| 洛阳市| 天柱县| 陵水| 集安市| 清水县| 台南县| 凤山市| 项城市| 弋阳县| 广元市| 上栗县| 张家港市| 定兴县| 阆中市| 新闻| 汤原县| 酒泉市| 定边县| 英德市| 中超| 中宁县| 皮山县| 错那县| 荔浦县| 灵寿县| 宝兴县| 朝阳县| 郁南县| 雷州市| 申扎县|