-
变量和数据类型
-
基本数据类型
- 布尔类型 bool
- 有符号整型 int
- 无符号整型 uint
- 浮点型 float
-
向量类型
类型 描述 vec2,vec3,vec4 2分量、3分量、4分量浮点向量 ivec2,ivec3,ivec4 2分量、3分量、4分量整型向量 uvec2,uvec3,uvec4 2分量、3分量、4分量无符号整型向量 uvec2,uvec3,uvec4 2分量、3分量、4分量布尔向量 -
矩阵类型 所有矩阵类型都只支持浮点型
类型 描述 mat2,mat2x2 两行两列 mat3,mat3x3 三行三列 mat4,mat4x4 四行四列 mat2x3 两行三列 mat2x4 两行四列 mat3x2 三行两列 mat3x4 三行四列 mat4x2 四行两列 mat4x3 四行三列
-
-
存储限定符
类型 描述 <none> 只是普通的本地变量,外部不可见,外部不可访问 const 一个编译时常量,或者说是一个对函数来说为只读的参数 in/varying 一个从前面阶段传递过来的变量 in centroid 一个从前面阶段传递过来的变量,使用质心插值 out/attribute 传递到下一个处理阶段或者在一个函数中指定一个返回值 out centroid 传递到下一个处理阶段,使用质心插值 inout 一个读/写变量,只能用于局部函数参数 uniform 一个从客户端代码传递过来的变量,在顶点之间不做改变 -
着色器的编译、绑定和链接的基本步骤
- 创建一个顶点着色器对象和一个片元着色器对象
- 将源代码连接到每个着色器对象
- 编译着色器对象
- 创建一个程序对象
- 将编译后的着色器对象连接到程序对象
- 链接程序对象
-
FrameBuffer与RenderBuffer
首先看一下两者的关系图
官方文档着这样说的:
A renderbuffer object is a 2D image buffer allocated by the application. The renderbuffer can be used to allocate and store color, depth, or stencil values and can be used as a color, depth, or stencil attachment in a framebuffer object. A renderbuffer is similar to an off-screen window system provided drawable surface, such as a pbuffer. A renderbuffer, however, cannot be directly used as a GL texture. ⼀个renderbuffer对象是应⽤分配的一个2D图像缓存区。renderbuffer能够被用来分配和存储颜色、深度或者模板值。也能够在一个framebuffer中被用作颜色、深度、模板的附件。⼀个renderbuffer是一个类似于屏幕窗口系统提供可绘制的表面。⽐如pBuffer。⼀个renderbuffer, 并不能直接被当做⼀个GL纹理使用。 A framebuffer object (often referred to as an FBO) is a collection of color, depth, and stencil buffer attachment points; state that describes properties such as the size and format of the color, depth, and stencil buffers attached to the FBO; and the names of the texture and renderbuffer objects attached to the FBO. Various 2D images can be attached to the color attachment point in the framebuffer object. These include a renderbuffer object that stores color values, a mip-level of a 2D texture or a cube map face, or even a mip-level of a 2D slice in a 3D texture. Similarly, various 2D images contain-ing depth values can be attached to the depth attachment point of an FBO. These can include a renderbuffer, a mip-level of a 2D texture or a cubemap face that stores depth values. The only 2D image that can be attached to the stencil attachment point of an FBO is a renderbuffer object that stores stencil values. ⼀个frameBuffer对象(通常被称为⼀个FBO)。是一个颜色、深度和模板缓存区附着点的集合。描述属性的状态,例如颜⾊、深度和模板缓存区的⼤⼩和格式,都关联到FBO(Frame Buffer Object)。并且纹理的名字和renderBuffer对象也都是关联于FBO。各种各样的2D图形能够被附着framebuffer对象的颜色附着点。它们包含了renderbuffer对象存储的颜色值、一个2D纹理或⽴⽅体贴图。或者一个mip-level的⼆维切面在3D纹理。同样,各种各样的2D图形包含了当时的深度值可以附加到⼀个FBO的深度附着点钟去。唯一的二维图像,能够附着在FBO的模板附着点,是一个renderbuffer对象存储模板值。
还是比较难懂通俗点说framebuffer并非是个缓冲区他是一个包含一个或多个附件的聚合器对象,它们依次是实际的缓冲区。你可以理解帧缓冲器作为C结构,其中每个成员都是指向缓冲区的指针。没有任何附件,帧缓冲器对象的占用空间非常小。renderbuffer是一个实际的缓冲区(一个字节数组,或整数,或像素)。在运用的时候呢RenderBuffer需要附着于FrameBuffer, FrameBuffer管理RenderBuffer, 需要先设置RenderBuffer, 然后和FramBuffer进行绑定操作, 后面的绘制才能起到作用 -
利用自定义着色器渲染一个图片代码
-
顶点着色器代码(着色器代码其实就是字符串)
//顶点坐标 attribute vec4 position; //纹理坐标(应为片元着色器无法接收到通过attribute传递的坐标信息,所以只能先传到顶点着色器然后桥接给片元着色器) attribute vec2 textCoordinate; //桥接纹理坐标参数 varying lowp vec2 varyTextCoord; //这里有多少个顶点main函数就会执行多少次 void main() { varyTextCoord = textCoordinate; //gl_Position内建变量赋值就好 gl_Position = position; }
1. 片元着色器代码 ``` //首先定义所有的顶点信息都是高精度的 precision highp float; //用来接收顶点着色器传递的参数(切记参数要和顶点着色器声明的一样) varying lowp vec2 varyTextCoord; //接收客户端传递的纹理ID(应为纹理已经被加载进来了所以只需要传递纹理id) uniform sampler2D colorMap; //这里又多少个像素点就会执行所少次 void main() { //获取每个像素点的颜色值(纹素) gl_FragColor = texture2D(colorMap, varyTextCoord); } ``` 1. 着色器的编译、绑定、链接 ``` /** 创建一个顶点着色器对象和一个片元着色器对象 将源代码连接到每个着色器对象 编译着色器对象 创建一个程序对象 将编译后的着色器对象连接到程序对象 */ -(GLuint)loadShaders:(NSString *)vert Withfrag:(NSString *)frag{ //1.创建两个临时的着色器对象 GLuint verShader,fragShader; //创建一个程序program GLuint program = glCreateProgram(); //2.编译两个着色器 [self compileShader:&verShader type:GL_VERTEX_SHADER file:vert]; [self compileShader:&fragShader type:GL_FRAGMENT_SHADER file:frag]; //3.创建最终程序(将编译后的着色器对象连接到程序对象) glAttachShader(program, verShader); glAttachShader(program, fragShader); //4.此时着色器已经添加到程序上了了已经不需要了所以释放 glDeleteShader(verShader); glDeleteShader(fragShader); return program; } //编译shader /** shader 着色器对象 type 着色器类型 file 着色器代码(就是一个字符串的路径) */ - (void)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file{ //1.先读取文件路径的字符串(就是着色器代码) NSString * content = [NSString stringWithContentsOfFile:file encoding:NSUTF8StringEncoding error:nil]; //转换一下字符串类型(OC字符串类型转成C++字符串类型) const GLchar *source = (GLchar *)[content UTF8String]; //2.根据类型来创建着色器 *shader = glCreateShader(type); //3.将着色的源码附着在着色器对象上面 //参数1:shader,要编译的着色器对象 *shader //参数2:numOfStrings,传递的源码字符串数量 1个 //参数3:strings,着色器程序的源码(真正的着色器程序源码) //参数4:lenOfStrings,长度,具有每个字符串长度的数组,或NULL,这意味着字符串是NULL终止的 glShaderSource(*shader, 1, &source, NULL); //4.将着色器源码编译成目标代码 glCompileShader(*shader); } ``` 1. 获取和设置属性 ``` //(2).设置合适的格式从buffer里面读取数据 glEnableVertexAttribArray(position); //(3).设置读取方式 //参数1:index,顶点数据的索引 //参数2:size,每个顶点属性的组件数量,1,2,3,或者4.默认初始值是4. //参数3:type,数据中的每个组件的类型,常用的有GL_FLOAT,GL_BYTE,GL_SHORT。默认初始值为GL_FLOAT //参数4:normalized,固定点数据值是否应该归一化,或者直接转换为固定值。(GL_FALSE) //参数5:stride,连续顶点属性之间的偏移量,默认为0; //参数6:指定一个指针,指向数组中的第一个顶点属性的第一个组件。默认为0 glVertexAttribPointer(position, 3, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 5, NULL); //处理纹理数据 GLuint textCoor = glGetAttribLocation(self.myPrograme, "textCoordinate"); glEnableVertexAttribArray(textCoor); glVertexAttribPointer(textCoor, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 5, (float *)NULL + 3); //加载纹理 [self setupTexture:@"daitu"]; //设置纹理采样器sampler2D glUniform1i(glGetUniformLocation(self.myPrograme, "colorMap"), 0); glDrawArrays(GL_TRIANGLES, 0, 6); //从渲染缓冲区显示到屏幕上 [self.myContext presentRenderbuffer:GL_RENDERBUFFER]; ``` -
完整代码: github.com/Bore-TuDou/…