Opengl学习1- draw line on ios

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
//
// ZYGLView.m
// esgl_1
//
// Created by zhangyun on 2017/10/9.
// Copyright © 2017年 zhangyun. All rights reserved.
//
#import "ZYGLView.h"
#import <GLKit/GLKit.h>
#import "VFMatrix.h"
typedef struct{
CGFloat red;
CGFloat green;
CGFloat blue;
CGFloat alpha;
}RGBAColor;
// vertex attribute struct
typedef struct {
GLfloat Position[3];
GLfloat Color[4];
}VFVertex;
// 白色
static const GLfloat whiteColor[] = {1,1,1,1};
static const RGBAColor kDefaultColor = {0.4,0.7,0.9,1.f};
// 4个顶点的数据
static const VFVertex crossLinesVertices[] = {
// line one
{0.5f,0.5f,0.f},
{-0.5f,-0.5f,0.f},
// line two
{-0.53f,0.48f,0.f},
{0.55f,-0.4f,0.f}
};
@interface ZYGLView(){
GLint programID;
}
@property (nonatomic,strong) EAGLContext *ctx;
@property (nonatomic,assign) GLfloat windowScale;
@end
@implementation ZYGLView
+ (Class)layerClass{
return [CAEAGLLayer class];
}
- (instancetype)initWithFrame:(CGRect)frame{
if (self = [super initWithFrame:frame]) {
CAEAGLLayer *layer = (CAEAGLLayer *)self.layer;
layer.drawableProperties = @{kEAGLDrawablePropertyColorFormat: kEAGLColorFormatRGBA8,kEAGLDrawablePropertyRetainedBacking:@(YES)};
layer.contentsScale = [UIScreen mainScreen].scale;
layer.opaque = YES;
}
return self;
}
- (void)prepare{
// 1.设置上下文环境
EAGLContext *ctx = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
[EAGLContext setCurrentContext:ctx];
self.ctx = ctx;
// 2. 设置背景颜色
glClearColor(kDefaultColor.red, kDefaultColor.green, kDefaultColor.blue, kDefaultColor.alpha);
// 3. 配置rbo
GLuint rboId;
glGenRenderbuffers(1, &rboId);
glBindRenderbuffer(GL_RENDERBUFFER, rboId);
// 4. 配置fbo
GLuint fboId;
glGenFramebuffers(1, &fboId);
glBindFramebuffer(GL_FRAMEBUFFER, fboId);
// 5. 绑定fbo rbo
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rboId);
// 6. 绑定renderbuffer到绘制表面
[ctx renderbufferStorage:GL_RENDERBUFFER fromDrawable:(CAEAGLLayer *)self.layer];
// 7. 下面的shader的内容
GLuint vertexId = [self addShader:GL_VERTEX_SHADER];
GLuint fragmentId = [self addShader:GL_FRAGMENT_SHADER];
if (vertexId ==0 || fragmentId == 0) {
return;
}
// 8. 创建program
GLuint programId = glCreateProgram();
// 9. 添加shader 到program
glAttachShader(programId, vertexId);
glAttachShader(programId, fragmentId);
// 10. 设置attribute 的index
glBindAttribLocation(programId, 0, "v_Position");
glBindAttribLocation(programId, 1, "v_Color");
// 11. link program
glLinkProgram(programId);
GLint linkSuccess;
// 检查是否链接成功
glGetProgramiv(programId, GL_LINK_STATUS, &linkSuccess);
if (linkSuccess == GL_FALSE) {
GLint infoLen;
glGetProgramiv(programId, GL_INFO_LOG_LENGTH, &infoLen);
if (infoLen > 0) {
GLchar *msg = malloc(sizeof(GLchar *) * infoLen);
glGetProgramInfoLog(programId, infoLen,NULL, msg);
NSString *str = [NSString stringWithUTF8String:msg];
NSLog(@"**---->shader link error:%@",str);
free(msg);
}
NSLog(@"**---->shader link error return");
return;
}
programID = programId;
// 12. 重置渲染内存
glClear(GL_COLOR_BUFFER_BIT);
// 13. 设置视窗
GLint renderbufW,renderbufH;
// 获取当前设备窗口的宽高
glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &renderbufW);
glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &renderbufH);
glViewport(0, 0, renderbufW, renderbufH);
// 获取宽高比,用来做坐标系转换
self.windowScale = ((GLfloat)renderbufW / (GLfloat)renderbufH);
// 14. 加载顶点数据
GLuint vboId;
glGenBuffers(1, &vboId);
const GLvoid *dataPtr;
GLsizeiptr dataSize;
GLsizei verticesIndicesCount;
dataSize = sizeof(crossLinesVertices);
dataPtr = crossLinesVertices;
verticesIndicesCount = (GLsizei)(sizeof(crossLinesVertices) / sizeof(crossLinesVertices[0]));
// vbo
glBindBuffer(GL_ARRAY_BUFFER, vboId);
glBufferData(GL_ARRAY_BUFFER, dataSize, dataPtr, GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
// 设置shader中postion数据
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(VFVertex), (const GLvoid *)offsetof(VFVertex,Position));
// 设置shader 中color数据
glDisableVertexAttribArray(1);
glVertexAttrib4fv(1, whiteColor);
}
- (void)display{
// 1. 使用program
glUseProgram(programID);
// 2. 坐标系转换,这块好复杂,没搞懂,直接使用了https://github.com/huangwenfei/OpenGLES2Learning 里的代码
VFMatrix4 scaleMat4 = VFMatrix4MakeScaleY(self.windowScale);
VFMatrix4 transMat4 = VFMatrix4Identity;
glUniformMatrix4fv(0, // 定义的 uniform 变量的内存标识符
1, // 不是 uniform 数组,只是一个 uniform -> 1
GL_FALSE, // ES 下 只能是 False
(const GLfloat *)scaleMat4.m1D); // 数据的首指针
glUniformMatrix4fv(1, // 定义的 uniform 变量的内存标识符
1, // 不是 uniform 数组,只是一个 uniform -> 1
GL_FALSE, // ES 下 只能是 False
(const GLfloat *)transMat4.m1D); // 数据的首指针
glLineWidth(10);
// 2. 绘制
glDrawArrays(GL_LINES, 0, 4);
// 3. 展示renderbuffer内容
[self.ctx presentRenderbuffer:GL_RENDERBUFFER];
}
- (GLuint)addShader:(GLenum)type{
NSString *fileName;
if (type == GL_VERTEX_SHADER) {
fileName = @"vertex.glsl";
}else{
fileName = @"fragment.glsl";
}
// 1. 从文件中加载shader代码
NSString *path = [[NSBundle mainBundle] pathForResource:fileName ofType:nil];
NSString *shaderSource = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:nil];
const GLchar *stringDatas = [shaderSource UTF8String];
GLint stringLen = (GLint)shaderSource.length;
// 2. 创建shader
GLuint shaderId = glCreateShader(type);
// 3. 加载代码
glShaderSource(shaderId, 1, &stringDatas, &stringLen);
// 4. 编译
glCompileShader(shaderId);
GLint compileSuccess;
// 5. 检查是否编译成功
glGetShaderiv(shaderId, GL_COMPILE_STATUS, &compileSuccess);
if (compileSuccess == GL_FALSE) {
GLint infoLen;
glGetShaderiv(shaderId, GL_INFO_LOG_LENGTH, &infoLen);
if (infoLen > 0) {
GLchar *msg = malloc(sizeof(GLchar *) * infoLen);
glGetShaderInfoLog(shaderId, infoLen, NULL, msg);
NSString *msgS = [NSString stringWithUTF8String:msg];
NSLog(@"&&&-->shader erro: %@",msgS);
free(msg);
}
return 0;
}
return shaderId;
}
@end
文章目录
|