Opengles 繪製的方式
int GL_POINTS //將傳入的頂點座標作爲單獨的點繪製
int GL_LINES //將傳入的座標作爲單獨線條繪製,ABCDEFG六個頂點,繪製AB、CD、EF三條線
int GL_LINE_STRIP //將傳入的頂點作爲折線繪製,ABCD四個頂點,繪製AB、BC、CD三條線
int GL_LINE_LOOP //將傳入的頂點作爲閉合折線繪製,ABCD四個頂點,繪製AB、BC、CD、DA四條線。
int GL_TRIANGLES //將傳入的頂點作爲單獨的三角形繪製,ABCDEF繪製ABC,DEF兩個三角形
int GL_TRIANGLE_FAN //將傳入的頂點作爲扇面繪製,ABCDEF繪製ABC、ACD、ADE、AEF四個三角形
int GL_TRIANGLE_STRIP //將傳入的頂點作爲三角條帶繪製,ABCDEF繪製ABC,BCD,CDE,DEF四個三角形
opengles不能直接繪製圓形,而是通過將圓形分割成無限個三角形,這樣看起來就像是圓形了。
說明:畫了三角形、矩形、圓形基本可以確定,opengles 提供了兩個繪製接口
1.指定繪製模式(自帶繪製順序) 頂點繪製
GLES20.glDrawArrays(GLES20.GL_TRIANGLE_FAN, 0, vertexCount);
2.自定義繪製順序 索引繪製
GLES20.glDrawElements(GLES20.GL_TRIANGLES, drawOrder.length, GLES20.GL_UNSIGNED_SHORT, drawListBuffer);
這兩種都離不開:頂點座標,繪製順序 這兩個必備要素
圓形繪製直接使用 GLES20.GL_TRIANGLE_FAN 這種自帶的方式就可以了,或者自己寫方法實現這種繪製順序採用索引繪製也是一樣的,n越大越像圓形,繪製橢圓也類似,將半徑R分開成兩個來計算座標就好了
public class Circle {
private static final String TAG = Circle.class.getSimpleName();
private FloatBuffer vertexBuffer;
//頂點的個數
private int vertexCount;
//將圓形劃分成n等份
//每個頂點的座標個數
private final int COORDS_PER_VERTEX = 3;
private int vertexStride = COORDS_PER_VERTEX * 4;
//繪製形狀需要一個頂點着色程序和一個片段着色程序
private final String vertexShaderCode =
"attribute vec4 vPosition;" +
"void main() {" +
" gl_Position = vPosition;" +
"}";
private final String fragmentShaderCode =
"precision mediump float;" +
"uniform vec4 vColor;" +
"void main() {" +
" gl_FragColor = vColor;" +
"}";
private float radius;
private int count;
private float x;
private float y;
private float z;
private int program;
public Circle(float radius, int count, float x, float y, float z) {
this.radius = radius;
this.count = count;
this.x = x;
this.y = y;
this.z = z;
ByteBuffer bb = ByteBuffer.allocateDirect((count + 2) * COORDS_PER_VERTEX * 4);
bb.order(ByteOrder.nativeOrder());
vertexBuffer = bb.asFloatBuffer();
float[] coords = circleCoords();
Log.i(TAG, "Circle: " + Arrays.toString(coords));
vertexBuffer.put(coords);
vertexBuffer.position(0);
int vertexShader = GlRender_1.loadShader(GLES20.GL_VERTEX_SHADER, vertexShaderCode);
int fragmentShader = GlRender_1.loadShader(GLES20.GL_FRAGMENT_SHADER, fragmentShaderCode);
program = GLES20.glCreateProgram();
GLES20.glAttachShader(program, vertexShader);
GLES20.glAttachShader(program, fragmentShader);
GLES20.glLinkProgram(program);
}
/*
*將360°平均分成n 等份,求每個點的座標
* */
private float[] circleCoords() {
//將圓形切成n塊有n+1個頂點+圓心
vertexCount = count + 2;
float[] coords = new float[vertexCount * COORDS_PER_VERTEX];
int offset = 0;
coords[offset++] = x;
coords[offset++] = y;
coords[offset++] = z;
for (int i = 0; i < count + 1; i++) {
float angleInRadians = ((float) i / (float) count)
* ((float) Math.PI * 2f);
coords[offset++] = x + radius * (float) Math.sin(angleInRadians);
coords[offset++] = y + radius * (float) Math.cos(angleInRadians);
coords[offset++] = z;
}
return coords;
}
private int positionHandle;
private int colorHandle;
float color[] = {0.63671875f, 0.76953125f, 0.22265625f, 1.0f};
public void draw() {
GLES20.glUseProgram(program);
positionHandle = GLES20.glGetAttribLocation(program, "vPosition");
GLES20.glEnableVertexAttribArray(positionHandle);
GLES20.glVertexAttribPointer(positionHandle, COORDS_PER_VERTEX, GLES20.GL_FLOAT, false, vertexStride, vertexBuffer);
colorHandle = GLES20.glGetUniformLocation(program, "vColor");
GLES20.glUniform4fv(colorHandle, 1, color, 0);
//前三個點繪製一個三角形 後面是以(0,2,3)(0,3,4)(0,4,5)....
GLES20.glDrawArrays(GLES20.GL_TRIANGLE_FAN, 0, vertexCount);
GLES20.glDisableVertexAttribArray(positionHandle);
}
}
因爲屏幕寬高比的原因目前繪製出來的本身就是橢圓形,後面會再繼續探索矩陣變換相關,實現真的圓形