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);
}
}
因为屏幕宽高比的原因目前绘制出来的本身就是椭圆形,后面会再继续探索矩阵变换相关,实现真的圆形