ios sdk开放了opengl绘制功能,开发者可利用opengl的绘制来实现更多复杂的覆盖物绘制。
bmkmapviewdelegate中的-mapview:ondrawmapframe:,地图渲染每一帧画面过程中,以及每次需要重绘地图时(例如添加覆盖物)都会调用此接口。开发者可以在这个接口中进行opengl的绘制。
不需要用户自己创建context和buffer,v5.0.0新增opengl映射矩阵(getprojectionmatrix)和视图矩阵(getviewmatrix)接口,用于3d绘制场景,具体代码请参考baidumap_iossdk_sample bmkopenglespage。
下面代码以在地图上绘制3d立方体为例,介绍如何使用opengl绘制接口。
-(void)init3dshader{//顶点着色器nsstring*vertexshader = @"precision highp float;attribute vec3 avertex;attribute vec4 acolor;uniform mat4 aviewmatrix;uniform mat4 aprojectionmatrix;uniform mat4 atransformmatrix;uniform mat4 ascalematrix;varying vec4 color;voidmain(){gl_position = aprojectionmatrix * aviewmatrix *vec4(avertex,1.0);color = acolor;}";//片段着色器nsstring*fragmentshader = @"precision highp float;varying vec4 color;voidmain(){gl_fragcolor = color;}";// program对象是可以附加着色器对象的对象// 创建一个空program并返回一个可以被引用的非零值(program id)_program3d =glcreateprogram();gluint vshader =glcreateshader(gl_vertex_shader);gluint fshader =glcreateshader(gl_fragment_shader);glint vlength =(glint)[vertexshader length];glint flength =(glint)[fragmentshader length];constglchar*vbyte =[vertexshader utf8string];constglchar*fbyte =[fragmentshader utf8string];glshadersource(vshader,1,&vbyte,&vlength);glshadersource(fshader,1,&fbyte,&flength);//成功编译着色器对象glcompileshader(vshader);glcompileshader(fshader);//成功地将着色器对象附加到program 对象glattachshader(_program3d, vshader);glattachshader(_program3d, fshader);//成功的链接program 对象之后gllinkprogram(_program3d);//查询由program指定的先前链接的程序对象_vertexlocation3d =glgetattriblocation(_program3d,"avertex");//表示程序对象中特定统一变量的位置_viewmatrixlocation3d =glgetuniformlocation(_program3d,"aviewmatrix");//得到名字为“aprojectionmatrix”在shader中的位置_projectionmatrixlocation3d =glgetuniformlocation(_program3d,"aprojectionmatrix");_colorlocation3d =glgetattriblocation(_program3d,"acolor");}
-(void)init3dvertext{//创建vertexfloat vertext[]={0.0,0.0,0.0,1.0,0.0,0.0,1.0,1.0,0.0,0.0,1.0,0.0,0.0,0.0,1.0,1.0,0.0,1.0,1.0,1.0,1.0,0.0,1.0,1.0,};for(int i =0; i <24; i){// 对标墨卡托坐标_vertext[i]= vertext[i]*10000;}short indices[]={0,4,5,0,5,1,1,5,6,1,6,2,2,6,7,2,7,3,3,7,4,3,4,0,4,7,6,4,6,5,3,0,1,3,1,2,};for(int i =0; i <36; i){_indecies[i]= indices[i];}float colors[]={1.0f,0.0f,0.0f,1.0f,0.0f,1.0f,0.0f,1.0f,0.0f,0.0f,1.0f,1.0f,1.0f,1.0f,0.0f,1.0f,0.0f,1.0f,1.0f,1.0f,1.0f,0.0f,1.0f,1.0f,0.0f,0.0f,0.0f,1.0f,1.0f,1.0f,1.0f,1.0f,};for(int i =0; i <32; i){_color[i]= colors[i];}}
-(void)drawframefor3dcube {if(_program3d ==0){[self init3dshader];[self init3dvertext];}glboolean depthmask =0;glgetbooleanv(gl_depth_writemask,&depthmask);gluseprogram(_program3d);glenable(gl_depth_test);if(depthmask ==gl_false){gldepthmask(gl_true);}glenablevertexattribarray(_vertexlocation3d);glvertexattribpointer(_vertexlocation3d,3,gl_float,false,0, _vertext);glenablevertexattribarray(_colorlocation3d);glvertexattribpointer(_colorlocation3d,4,gl_float,false,0, _color);bmkmappoint center =bmkmappointforcoordinate(cllocationcoordinate2dmake(39.965,116.404));cgpoint offsetpoint =[self.mapview glpointformappoint:center];float *viewmatrix =[self.mapview getviewmatrix];translatem(viewmatrix,0, offsetpoint.x, offsetpoint.y,0);float *projectionmatrix =[self.mapview getprojectionmatrix];//传值函数,该函数的第一个参数是该变量在shader中的位置,第二个参数是被赋值的矩阵的数目。第三个参数表明在向uniform变量赋值时该矩阵是否需要转置//vec4类型的变量赋值,我们可以使用gluniform4f或者gluniform4fv。v代表数组gluniformmatrix4fv(_viewmatrixlocation3d,1,false, viewmatrix);gluniformmatrix4fv(_projectionmatrixlocation3d,1,false, projectionmatrix);gldrawelements(gl_triangles,36,gl_unsigned_short, _indecies);gldisablevertexattribarray(_vertexlocation3d);gldisablevertexattribarray(_colorlocation3d);gldisable(gl_depth_test);gldepthmask(depthmask);}
/**地图渲染每一帧画面过程中,以及每次需要重新绘制地图时(例如添加覆盖物)都会调用此方法@param mapview 地图view@param status 地图的状态*/-(void)mapview:(bmkmapview*)mapview ondrawmapframe:(bmkmapstatus*)status {[self drawframefor3dcube];}
效果如图:
上一篇
下一篇
本篇文章对您是否有帮助?