使用Android SDK开发,使用OpenGL ES2.0绘制圆形点,支持横竖屏转换,点的大小有两种方式设置效果图如下:
着色器代码
package com.hb.drawpoint;
public final class ShaderCode {
public final static String VERTEX =
"uniform mat4 u_Matrix;" +
"attribute vec4 a_Position;" +
"attribute vec4 a_Color;" +
"attribute float a_PointSize;" +
"varying vec4 v_Color;" +
"void main()" +
"{" +
" gl_Position = u_Matrix * a_Position;" +
" gl_PointSize = a_PointSize;" +
" v_Color = a_Color;" +
"}";
public final static String FRAGMENT =
"precision mediump float;" +
"varying vec4 v_Color;" +
"void main()" +
"{" +
" float d = distance(gl_PointCoord, vec2(0.5, 0.5));" +
" if(d < 0.5) " +
" {gl_FragColor = v_Color;} " +
" else { discard; }" +
"}";
}
核心渲染代码
package com.hb.drawpoint;
import android.opengl.GLSurfaceView;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
import static android.opengl.GLES20.GL_COLOR_BUFFER_BIT;
import static android.opengl.GLES20.GL_FLOAT;
import static android.opengl.GLES20.GL_POINTS;
import static android.opengl.GLES20.glClear;
import static android.opengl.GLES20.glClearColor;
import static android.opengl.GLES20.glDrawArrays;
import static android.opengl.GLES20.glEnableVertexAttribArray;
import static android.opengl.GLES20.glGetAttribLocation;
import static android.opengl.GLES20.glGetUniformLocation;
import static android.opengl.GLES20.glUniformMatrix4fv;
import static android.opengl.GLES20.glUseProgram;
import static android.opengl.GLES20.glVertexAttrib1f;
import static android.opengl.GLES20.glVertexAttribPointer;
import static android.opengl.GLES20.glViewport;
import static android.opengl.Matrix.orthoM;
public final class MapRender implements GLSurfaceView.Renderer {
private static final String A_POSITION = "a_Position";
private static final String A_COLOR = "a_Color";
private static final String A_SIZE = "a_PointSize";
private static final String U_MATRIX = "u_Matrix";
private static final int POSITION_COMPONENT_COUNT = 2;
private static final int SIZE_COMPONENT_COUNT = 1;
private static final int COLOR_COMPONENT_COUNT = 3;
private static final int BYTES_PER_FLOAT = 4;
private static final int STRIDE =
(POSITION_COMPONENT_COUNT + COLOR_COMPONENT_COUNT + SIZE_COMPONENT_COUNT) * BYTES_PER_FLOAT;
private final FloatBuffer vertexData;
private final float[] projectionMatrix = new float[16];
private int program;
private int aPositionLocation;
private int aColorLocation;
private int aSizeLocation;
private int uMatrixLocation;
public MapRender() {
float[] tableVerticesWithTriangles = {
0f, -0.25f, 0f, 0f, 1f, 200f,
0f, 0.25f, 1f, 0f, 0f, 100f
};
vertexData = ByteBuffer
.allocateDirect(tableVerticesWithTriangles.length * BYTES_PER_FLOAT)
.order(ByteOrder.nativeOrder()).asFloatBuffer();
vertexData.put(tableVerticesWithTriangles);
}
@Override
public void onSurfaceCreated(GL10 gl10, EGLConfig eglConfig) {
glClearColor(0.0f, 1.0f, 1.0f, 1.0f);
int vertexShader = ShaderHelper.compileVertexShader(ShaderCode.VERTEX);
int fragmentShader = ShaderHelper
.compileFragmentShader(ShaderCode.FRAGMENT);
program = ShaderHelper.linkProgram(vertexShader, fragmentShader);
glUseProgram(program);
aPositionLocation = glGetAttribLocation(program, A_POSITION);
aColorLocation = glGetAttribLocation(program, A_COLOR);
aSizeLocation = glGetAttribLocation(program, A_SIZE);
uMatrixLocation=glGetUniformLocation(program,U_MATRIX);
vertexData.position(0);
glVertexAttribPointer(aPositionLocation, POSITION_COMPONENT_COUNT, GL_FLOAT,
false, STRIDE, vertexData);
glEnableVertexAttribArray(aPositionLocation);
vertexData.position(POSITION_COMPONENT_COUNT);
glVertexAttribPointer(aColorLocation, COLOR_COMPONENT_COUNT, GL_FLOAT,
false, STRIDE, vertexData);
glEnableVertexAttribArray(aColorLocation);
// vertexData.position(POSITION_COMPONENT_COUNT+COLOR_COMPONENT_COUNT);
// glVertexAttribPointer(aSizeLocation, SIZE_COMPONENT_COUNT, GL_FLOAT,
// false, STRIDE, vertexData);
//
// glEnableVertexAttribArray(aSizeLocation);//使用缓冲区赋值
glVertexAttrib1f(aSizeLocation, 100f);//统一赋值点大小
}
@Override
public void onSurfaceChanged(GL10 gl10, int width, int height) {
glViewport(0, 0, width, height);
//设置支持横竖屏转换
final float aspectRatio = width > height ?
(float) width / (float) height :
(float) height / (float) width;
if (width > height) {
// Landscape
orthoM(projectionMatrix, 0, -aspectRatio, aspectRatio, -1f, 1f, -1f, 1f);
} else {
// Portrait or square
orthoM(projectionMatrix, 0, -1f, 1f, -aspectRatio, aspectRatio, -1f, 1f);
}
}
@Override
public void onDrawFrame(GL10 gl10) {
glClear(GL_COLOR_BUFFER_BIT);
glUniformMatrix4fv(uMatrixLocation, 1, false, projectionMatrix, 0);
glDrawArrays(GL_POINTS, 0, 2);
}
}
全部源代码地址在码云https://gitee.com/GISuser/DrawPoint