GLuint vertShader, fragShader; NSURL *vertShaderURL, *fragShaderURL; self.program = glCreateProgram(); // Create and compile the vertex shader. vertShaderURL = [[NSBundle mainBundle] URLForResource:@"Shader" withExtension:@"vsh"]; if (![self compileShader:&vertShader type:GL_VERTEX_SHADER URL:vertShaderURL]) { NSLog(@"Failed to compile vertex shader"); return NO; } // Create and compile fragment shader. fragShaderURL = [[NSBundle mainBundle] URLForResource:@"Shader" withExtension:@"fsh"]; if (![self compileShader:&fragShader type:GL_FRAGMENT_SHADER URL:fragShaderURL]) { NSLog(@"Failed to compile fragment shader"); return NO; } // Attach vertex shader to program. glAttachShader(self.program, vertShader); // Attach fragment shader to program. glAttachShader(self.program, fragShader); // Bind attribute locations. This needs to be done prior to linking. glBindAttribLocation(self.program, ATTRIB_VERTEX, "position"); glBindAttribLocation(self.program, ATTRIB_TEXCOORD, "texCoord");
首先翻译一下得出两个关键词:点、面
生成一个OpenGL程序需要两个函数
varying highp vec2 texCoordVarying; precision mediump float; uniform sampler2D SamplerY; uniform sampler2D SamplerUV; uniform mat3 colorConversionMatrix; void main() { mediump vec3 yuv; lowp vec3 rgb; // Subtract constants to map the video range start at 0 yuv.x = (texture2D(SamplerY, texCoordVarying).r);// - (16.0/255.0)); yuv.yz = (texture2D(SamplerUV, texCoordVarying).ra - vec2(0.5, 0.5)); rgb = colorConversionMatrix * yuv; gl_FragColor = vec4(rgb,1); // gl_FragColor = vec4(1, 0, 0, 1); }
shader.fsh
attribute vec4 position; attribute vec2 texCoord; uniform float preferredRotation; uniform mat4 projectionMatrix; uniform mat4 modelViewMatrix; varying vec2 texCoordVarying; void main() { mat4 rotationMatrix = mat4( cos(preferredRotation), -sin(preferredRotation), 0.0, 0.0, sin(preferredRotation), cos(preferredRotation), 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0); gl_Position = projectionMatrix * modelViewMatrix * rotationMatrix * position;// * modelViewMatrix * projectionMatrix; texCoordVarying = texCoord; }
shader.vsh
这两个函数中有varying或varying标明的两个同名属性字段,测试结果是必须同名而且是两个函数之间互通使用的
在main函数上方设定的额参数,均是后面添加设定的参数,设置方法有:
在OpenGL ES中,uniform的位置不是固定的,必须在Program link完成之后才能够获得: / Get uniform locations. uniforms[UNIFORM_Y] = glGetUniformLocation(self.program, "SamplerY"); uniforms[UNIFORM_UV] = glGetUniformLocation(self.program, "SamplerUV"); uniforms[UNIFORM_ROTATE] = glGetUniformLocation(self.program, "preferredRotation"); uniforms[UNIFORM_COLOR_CONVERSION_MATRIX] = glGetUniformLocation(self.program, "colorConversionMatrix"); uniforms[UNIFORM_PROJECTION_MARTRIX] = glGetUniformLocation(self.program, "projectionMatrix"); uniforms[UNIFORM_MODELVIEW_MARTRIX] = glGetUniformLocation(self.program, "modelViewMatrix"); /Set uniform glUniform1i(uniforms[UNIFORM_Y], 0); glUniform1i(uniforms[UNIFORM_UV], 1); glUniform1f(uniforms[UNIFORM_ROTATE], GLKMathDegreesToRadians(180)); // Bind attribute locations. This needs to be done prior to linking. glBindAttribLocation(self.program, ATTRIB_VERTEX, "position"); glBindAttribLocation(self.program, ATTRIB_TEXCOORD, "texCoord");
//初始化纹理数据
glGenBuffers(1, &_textureBuffer);
glBindBuffer(GL_ARRAY_BUFFER, _textureBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(sphereTexCoords), sphereTexCoords, GL_STATIC_DRAW);
//启用纹理数据
glBindBuffer(GL_ARRAY_BUFFER, _textureBuffer);
glVertexAttribPointer(ATTRIB_TEXCOORD, 2, GL_FLOAT, GL_FALSE, 0, NULL);
glEnableVertexAttribArray(ATTRIB_TEXCOORD);
glVertexAttribPointer (GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr)
glVertexAttribPointer(取值纹理对象, 每次取值数目, 取值类型, GL_FALSE, 间隔大小,开始取值位置);
变量赋值
三个可以赋值给我们的变量的标签
- Uniforms:在渲染循环里作为不变的输入值
- Attributes:随顶点位置不同会变的输入值
- Varyings:用来在Vertex shader和Fragment shader之间传递信息的,比如在Vertex shader中写入varying值,然后就可以在Fragment shader中读取和处理
向量
有很多种向量,但是有三种会经常看到
- vec2:两个浮点数,适合在Fragment shader中保存X和Y坐标的情况
- vec3:三个浮点数
- vec4:四个浮点数,在图像处理中持续追踪每个像素的R,G,V,A这四个值。
矩阵
是浮点数组的数组。三个经常处理的矩阵对象
- mat2:相当于保存了两个vec2对象的值或四个浮点数。
- mat3
- mat4
作者:星光社的戴铭
链接:https://www.jianshu.com/p/8687a040eb48