OpenGL ES 渲染立体图形
程序员文章站
2022-05-07 19:09:44
一、理解 顶点数据存储在申请的缓冲区中,其由数据总线传递给着色器(如果是片元着色器,还须将顶点转换成片元),再由着色器最终渲染到涂层上; 二、思路 1.设置涂层; 2.创建上下文; 3.清空缓存区; 4.创建渲染缓存区和帧缓存区; 5.开始绘制; 三、核心代码 //最终渲染 四、效果 GitHub ......
一、理解
顶点数据存储在申请的缓冲区中,其由数据总线传递给着色器(如果是片元着色器,还须将顶点转换成片元),再由着色器最终渲染到涂层上;
二、思路
1.设置涂层;
2.创建上下文;
3.清空缓存区;
4.创建渲染缓存区和帧缓存区;
5.开始绘制;
三、核心代码
//最终渲染
- (void)renderlayer { //设置窗口背景颜色 glclearcolor(0.0, 0.0, 0.0, 1.0); //清空颜色缓存 glclear(gl_color_buffer_bit); //设置视口大小 cgfloat scale = [[uiscreen mainscreen] scale]; glviewport(self.frame.origin.x*scale, self.frame.origin.y*scale, self.frame.size.width*scale, self.frame.size.height*scale); //读取顶点和片元着色器程序 nsstring *vertfile = [[nsbundle mainbundle] pathforresource:@"shaderv" oftype:@"glsl"]; nsstring *fragfile = [[nsbundle mainbundle] pathforresource:@"shaderf" oftype:@"glsl"]; nslog(@"vertfile:%@", vertfile); nslog(@"fragfile:%@", fragfile); //判断myprogram是否存在,存在则清空 if (self.myprogram) { gldeleteprogram(self.myprogram); self.myprogram = 0; } //加载着色器到myprogram中 self.myprogram = [self loadshader:vertfile frag:fragfile]; //创建链接 gllinkprogram(self.myprogram); glint linksuccess; //获取链接状态 glgetprogramiv(self.myprogram, gl_link_status, &linksuccess); //判断链接是否成功 if (linksuccess == gl_false) { //获取失败信息 glchar message[256]; glgetprograminfolog(self.myprogram, sizeof(message), 0, &message[0]); //c字符串转换成oc字符串 nsstring *messagestring = [nsstring stringwithutf8string:message]; nslog(@"error:%@", messagestring); return; } else { //使用myprogram gluseprogram(self.myprogram); } //创建绘制索引数组 gluint indices[] = { 0, 3, 2, 0, 1, 3, 0, 2, 4, 0, 4, 1, 2, 3, 4, 1, 4, 3 }; //判断顶点缓存区是否为空,为空则申请一个缓存区标志符 if (self.myvertices == 0) { glgenbuffers(1, &_myvertices); } //----------处理顶点坐标--------- /*顶点数据 1.前3个坐标值(x、y、z),后3个颜色值(rgb); 2.有先后顺序,否则绘制形状完全不同 */ glfloat attrarr[] = { -0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 1.0f, //左上 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 1.0f, //右上 -0.5f, -0.5f, 0.0f, 1.0f, 1.0f, 1.0f, //左下 0.5f, -0.5f, 0.0f, 1.0f, 1.0f, 1.0f, //右下 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, //顶点 }; //将_myvertices绑定到gl_array_buffer标志符上 glbindbuffer(gl_array_buffer, _myvertices); //把顶点坐标数据从cpu复制到gpu上 glbufferdata(gl_array_buffer, sizeof(attrarr), attrarr, gl_dynamic_draw); //将顶点坐标数据通过myprogram传递到顶点着色器程序的position //获取顶点属性入口 gluint position = glgetattriblocation(self.myprogram, "position"); /*传递数据 1.一行6个数据,前3个为坐标,后3个为颜色; 2.null开始位置:默认为0,指向数组首地址; */ glvertexattribpointer(position, 3, gl_float, gl_false, sizeof(glfloat)*6, null); //设置合适的格式从缓存区中读取数据 glenablevertexattribarray(position); //处理顶点颜色数据:传递到顶点着色器的positioncolor gluint positioncolor = glgetattriblocation(self.myprogram, "positioncolor"); glvertexattribpointer(positioncolor, 3, gl_float, gl_false, sizeof(glfloat)*6, (float *)null +3); glenablevertexattribarray(positioncolor); //在myprogram中找到透视投影矩阵和模型视图矩阵 gluint projectionmatrixslot = glgetuniformlocation(self.myprogram, "projectionmatrix"); gluint modelviewmatrixslot = glgetuniformlocation(self.myprogram, "modelviewmatrix"); //创建透视投影矩阵并初始化 float width = self.frame.size.width; float height = self.frame.size.height; ksmatrix4 _projectionmatrix; ksmatrixloadidentity(&_projectionmatrix); float aspect = width/height; ksperspective(&_projectionmatrix, 30.0, aspect, 5.0f, 20.0f); //设置glsl里面的投影矩阵 gluniformmatrix4fv(projectionmatrixslot, 1, gl_false, (glfloat *)&_projectionmatrix.m[0][0]); //开启剔除功能 glenable(gl_cull_face); //创建平移矩阵:z轴平移-10 ksmatrix4 _modelviewmatrix; ksmatrixloadidentity(&_modelviewmatrix); kstranslate(&_modelviewmatrix, 0.0, 0.0, -10.0); //创建旋转矩阵 ksmatrix4 _rotationmatrix; ksmatrixloadidentity(&_rotationmatrix); ksrotate(&_rotationmatrix, xdegree, 1.0, 0.0, 0.0); ksrotate(&_rotationmatrix, ydegree, 0.0, 1.0, 0.0); ksrotate(&_rotationmatrix, zdegree, 0.0, 0.0, 1.0); //将平移矩阵和旋转矩阵相乘,结果放到模型视图矩阵中 ksmatrixmultiply(&_modelviewmatrix, &_rotationmatrix, &_modelviewmatrix); //设置glsl里面的模型视图矩阵 gluniformmatrix4fv(modelviewmatrixslot, 1, gl_false, (glfloat *)&_modelviewmatrix.m[0][0]); //设置绘制参数:片元、个数、索引数组 gldrawelements(gl_triangles, sizeof(indices)/sizeof(indices[0]), gl_unsigned_int, indices); //由顶点着色器将缓存区中的数据渲染到显示涂层上 [self.mycontext presentrenderbuffer:gl_renderbuffer]; }
四、效果
上一篇: IO,File对象-构造函数和常用方法
下一篇: oracle数据库逐步学习总结【基础二】