上篇博客中我們已經(jīng)使用到了相機(jī)和投影域滥,利用變換矩陣昆汹,繪制出了等腰直角三角形。在本篇博客中树瞭,我們繪制正方形和圓形同樣少不了變換矩陣拇厢。
構(gòu)建正方形和圓形
前面提到過(guò)筏勒,在OpenGLES的世界里面是沒有正方形和圓形的,只有點(diǎn)旺嬉、線、三角形厨埋。三角形就是OpenGLES提供的最復(fù)雜的圖元單位邪媳。所以我們要繪制填充的正方形和圓形就需要利用三角形來(lái)實(shí)現(xiàn)。
正方形
正方形的構(gòu)建比較簡(jiǎn)單荡陷,可以用兩個(gè)三角形組成雨效。當(dāng)然,你也可以用很多很多三角形去合成一個(gè)正方形废赞,只要你樂意徽龟。如下圖所示,我們可以按照123組成的三角形和134組成的三角形唉地,兩個(gè)拼合成一個(gè)正方形据悔。
可以設(shè)置正方形的坐標(biāo)數(shù)組為:
static float triangleCoords[] = {
-0.5f, 0.5f, 0.0f, // top left
-0.5f, -0.5f, 0.0f, // bottom left
0.5f, -0.5f, 0.0f, // bottom right
0.5f, 0.5f, 0.0f // top right
};
圓形
圓形的構(gòu)建,相對(duì)復(fù)雜一點(diǎn)耘沼,我們可以把圓形看成一個(gè)正多邊形极颓,邊越多,圓越平滑群嗤。如下圖所示菠隆,分別為正六邊形、正八邊形狂秘、正十六邊形和正一百邊形骇径。
以六邊形為例,由012者春、023破衔,034、045钱烟、056运敢、061六個(gè)三角形,更多變形同樣如此忠售。
利用簡(jiǎn)單的數(shù)學(xué)知識(shí)传惠,即可得到,以多邊形中心建立直角坐標(biāo)系稻扬,得到n變形的頂點(diǎn)坐標(biāo)為:
private float[] createPositions(){
ArrayList<Float> data=new ArrayList<>();
data.add(0.0f); //設(shè)置圓心坐標(biāo)
data.add(0.0f);
data.add(0.0f);
float angDegSpan=360f/n;
for(float i=0;i<360+angDegSpan;i+=angDegSpan){
data.add((float) (radius*Math.sin(i*Math.PI/180f)));
data.add((float)(radius*Math.cos(i*Math.PI/180f)));
data.add(0.0f);
}
float[] f=new float[data.size()];
for (int i=0;i<f.length;i++){
f[i]=data.get(i);
}
return f;
}
圖形的繪制
得到了坐標(biāo)數(shù)組卦方,剩下的工作就和三角形的繪制基本相同了。唯一不同的地方泰佳,是需要修改:
GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, 1);
為:
GLES20.glDrawArrays(GLES20.GL_TRIANGLE_FAN, 0, shapePos.length/3);
GLES20.glDrawArrays的第一個(gè)參數(shù)表示繪制方式盼砍,第二個(gè)參數(shù)表示偏移量尘吗,第三個(gè)參數(shù)表示頂點(diǎn)個(gè)數(shù)。
繪制方式有:
int GL_POINTS //將傳入的頂點(diǎn)坐標(biāo)作為單獨(dú)的點(diǎn)繪制
int GL_LINES //將傳入的坐標(biāo)作為單獨(dú)線條繪制浇坐,ABCDEFG六個(gè)頂點(diǎn)睬捶,繪制AB、CD近刘、EF三條線
int GL_LINE_STRIP //將傳入的頂點(diǎn)作為折線繪制擒贸,ABCD四個(gè)頂點(diǎn),繪制AB觉渴、BC介劫、CD三條線
int GL_LINE_LOOP //將傳入的頂點(diǎn)作為閉合折線繪制,ABCD四個(gè)頂點(diǎn)案淋,繪制AB座韵、BC、CD踢京、DA四條線誉碴。
int GL_TRIANGLES //將傳入的頂點(diǎn)作為單獨(dú)的三角形繪制,ABCDEF繪制ABC,DEF兩個(gè)三角形
int GL_TRIANGLE_FAN //將傳入的頂點(diǎn)作為扇面繪制瓣距,ABCDEF繪制ABC翔烁、ACD、ADE旨涝、AEF四個(gè)三角形
int GL_TRIANGLE_STRIP //將傳入的頂點(diǎn)作為三角條帶繪制蹬屹,ABCDEF繪制ABC,BCD,CDE,DEF四個(gè)三角形
所以看到這里,正方形又多了個(gè)構(gòu)建方式:按照途中坐標(biāo)點(diǎn)1243的順序傳入白华,然后繪制時(shí)選擇GL_TRIANGLE_STRIP的繪制方式慨默。
最后繪制結(jié)果如下:
繪制小結(jié)
GL_TRIANGLE_STRIP
由上面的注釋,我們可以知道弧腥,GL_TRIANGLE_STRIP的方式繪制連續(xù)的三角形厦取,比直接用GL_TRIANGLES的方式繪制三角形少好多個(gè)頂點(diǎn),效率會(huì)高很多管搪。另外虾攻,GL_TRIANGLE_STRIP并不是只能繪制連續(xù)的三角形構(gòu)成的物體,我們只需要將不需要重復(fù)繪制的點(diǎn)重復(fù)兩次即可更鲁。比如霎箍,傳入ABCDEEFFGH坐標(biāo),就會(huì)得到ABC澡为、BCD漂坏、CDE以及FGH四個(gè)三角形。
GL_TRIANGLE_FAN
扇面繪制是以第一個(gè)為零點(diǎn)進(jìn)行繪制,通常我們繪制圓形顶别,圓錐的錐面都會(huì)使用到谷徙,值得注意的是,最后一個(gè)點(diǎn)的左邊應(yīng)當(dāng)與第二個(gè)點(diǎn)重合驯绎,在計(jì)算的時(shí)候完慧,起點(diǎn)角度為0度,終點(diǎn)角度應(yīng)包含360度剩失。
頂點(diǎn)法和索引法
上述提到的繪制屈尼,使用的都是GLES20.glDrawArrays
,也就是頂點(diǎn)法赴叹,是根據(jù)傳入的定點(diǎn)順序進(jìn)行繪制的。還有一個(gè)方法進(jìn)行繪制GLES20.glDrawElements
指蚜,稱之為索引法乞巧,是根據(jù)索引序列,在頂點(diǎn)序列中找到對(duì)應(yīng)的頂點(diǎn)摊鸡,并根據(jù)繪制的方式绽媒,組成相應(yīng)的圖元進(jìn)行繪制。
頂點(diǎn)法擁有的繪制方式免猾,索引法也都有是辕。相對(duì)于頂點(diǎn)法在復(fù)雜圖形的繪制中無(wú)法避免大量頂點(diǎn)重復(fù)的情況,索引法可以相對(duì)頂點(diǎn)法減少很多重復(fù)頂點(diǎn)占用的空間猎提。