本案例是使用OC语言完成的。
一、步骤
总的来说就6个步骤:
- 创建⼀个顶点着⾊器对象和⼀个⽚段着⾊器对象
- 将源代码链接到每个着⾊器对象
- 编译着⾊器对象
- 创建⼀个程序对象
- 将编译后的着⾊器对象连接到程序对象
- 链接程序对象
二、 使用到的方法解析
1.glCreateShader创建着色器
//type — 创建着⾊器的类型,GL_VERTEX_SHADER 或者GL_FRAGMENT_SHADER
//返回值 — 是指向新着⾊器对象的句柄.
GLuint glCreateShader(GLenum type);
2.glDeleteShader删除着⾊器
//shader — 要删除的着⾊器对象句柄
void glDeleteShader(GLuint shader);
3.glShaderSource将着色器源码附加到着色器对象上
//将着色器源码附加到着色器对象上。
//参数1:shader,要编译的着色器对象 *shader
//参数2:numOfStrings,传递的源码字符串数量 1个
//参数3:strings,着色器程序的源码(真正的着色器程序源码)
//参数4:lenOfStrings,长度,具有每个字符串长度的数组,或NULL,这意味着字符串是NULL终止的
glShaderSource(*shader, 1, &source,NULL);
4.把着色器源代码编译成目标代码
glCompileShader(*shader);
5.glCreateProgram 创建Program
//创建⼀个程序对象
//返回值: 返回⼀个执⾏新程序对象的句柄
GLUint glCreateProgram( )
6.glDeleteProgram 删除Program
void glDeleteProgram( GLuint program )
7.glAttachShader着⾊器与程序连接/附着
//着⾊器与程序连接/附着
//program : 指向程序对象的句柄
//shader : 指向程序连接的着⾊器对象的句柄
void glAttachShader( GLuint program , GLuint shader );
8.glDetachShader断开连接
//断开连接
void glDetachShader(GLuint program);
9.glLinkProgram链接Program
//program: 指向程序对象句柄
glLinkProgram(GLuint program)
10.检测链接是否成功
链接程序之后, 需要检查链接是否成功. 你可以使⽤glGetProgramiv 检查链接状态:
/**
program: 需要获取信息的程序对象句柄
pname : 获取信息的参数,可以是:
GL_ACTIVE_ATTRIBUTES
GL_ACTIVE_ATTRIBUTES_MAX_LENGTH
GL_ACTIVE_UNIFORM_BLOCK
GL_ACTIVE_UNIFORM_BLOCK_MAX_LENGTH
GL_ACTIVE_UNIFROMS
GL_ACTIVE_UNIFORM_MAX_LENGTH
GL_ATTACHED_SHADERS
GL_DELETE_STATUS
GL_INFO_LOG_LENGTH
GL_LINK_STATUS
GL_PROGRAM_BINARY_RETRIEVABLE_HINT
GL_TRANSFORM_FEEDBACK_BUFFER_MODE
GL_TRANSFORM_FEEDBACK_VARYINGS
GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH
GL_VALIDATE_STATUS
params : 指向查询结果整数存储位置的指针
**/
void glGetProgramiv (GLuint program,GLenum pname, GLint *params);
11.glGetPorgramInfoLog从程序信息⽇志中获取信息
从程序信息⽇志中获取信息/**
void glGetPorgramInfoLog( GLuint program ,GLSizei maxLength, GLSizei *length , GLChar *infoLog )
program : 指向需要获取信息的程序对象句柄
maxLength : 存储信息⽇志的缓存区⼤⼩
length : 写⼊的信息⽇志⻓度(减去null 终⽌符),如果不需要知道⻓度,这个参数可以为Null.
infoLog : 指向存储信息⽇志的字符缓存区的指针
program: 设置为活动程序的程序对象句柄.
**/
void glUseProgram(GLuint program)
12.RenderBUffe & FrameBuffer
- RenderBuffer:是一个通过应用分配的2D图像缓冲区,需要附着在FrameBuffer上
- FrameBuffer:是一个收集颜色、深度和模板缓存区的附着点,简称FBO,即是一个管理者,用来管理RenderBuffer,且FrameBuffer没有实际的存储功能,真正实现存储的是RenderBuffer
三、UIView中的代码
/*
不采样GLKBaseEffect,使用编译链接自定义的着色器(shader)。用简单的glsl语言来实现顶点、片元着色器,并图形进行简单的变换。
思路:
1.创建图层
2.创建上下文
3.清空缓存区
4.设置RenderBuffer
5.设置FrameBuffer
6.开始绘制
*/
#import <OpenGLES/ES2/gl.h>
#import "CCView.h"
@interface CCView()
//在iOS和tvOS上绘制OpenGL ES内容的图层,继承与CALayer
@property(nonatomic,strong)CAEAGLLayer *myEagLayer;
@property(nonatomic,strong)EAGLContext *myContext;
@property(nonatomic,assign)GLuint myColorRenderBuffer;
@property(nonatomic,assign)GLuint myColorFrameBuffer;
@property(nonatomic,assign)GLuint myPrograme;
@end
@implementation CCView
-(void)layoutSubviews
{
//1.设置图层
[self setupLayer];
//2.设置图形上下文
[self setupContext];
//3.清空缓存区
[self deleteRenderAndFrameBuffer];
//4.设置RenderBuffer
[self setupRenderBuffer];
//5.设置FrameBuffer
[self setupFrameBuffer];
//6.开始绘制
[self renderLayer];
}
//6.开始绘制
-(void)renderLayer
{
//设置清屏颜色
glClearColor(0.3f, 0.45f