本篇博文主要是实现用手指拖动OpenGL ES2.0绘图的屏幕,在使用了正摄投影与平移矩阵相结合,捕捉视图的move事件,将手指滑过的屏幕坐标转为绘图坐标系坐标,根据差值,对OpenGL ES绘图坐标系进行平移,从而得到需要的结果。效果图如下图所示:
核心代码如下:
1主要是计算点击事件的坐标差值,最后传递给Render
@SuppressLint("ClickableViewAccessibility")
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
if (motionEvent != null) {
pointerCount = motionEvent.getPointerCount();
final float normalizedX =
(motionEvent.getX() / (float) view.getWidth()) * 2 - 1;
final float normalizedY =
-((motionEvent.getY() / (float) view.getHeight()) * 2 - 1);
switch (motionEvent.getAction()) {
case MotionEvent.ACTION_DOWN:
Log.e(TAG, "点击事件");
X = normalizedX;
Y = normalizedY;
break;
case MotionEvent.ACTION_MOVE:
Log.e(TAG, "移动事件");
move(normalizedX - X, normalizedY - Y);
X = normalizedX;
Y = normalizedY;
break;
case MotionEvent.ACTION_UP:
Log.e(TAG, "抬起事件");
break;
case MotionEvent.ACTION_SCROLL:
Log.e(TAG, "滚动事件");
break;
default:
break;
}
return true;
} else {
return false;
}
}
2.进行计算与渲染
package com.map.core;
import android.opengl.GLSurfaceView;
import android.util.Log;
import com.map.brush.Brush;
import java.util.ArrayList;
import java.util.List;
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.glClear;
import static android.opengl.GLES20.glClearColor;
import static android.opengl.GLES20.glViewport;
import static android.opengl.Matrix.multiplyMM;
import static android.opengl.Matrix.orthoM;
import static android.opengl.Matrix.setIdentityM;
import static android.opengl.Matrix.translateM;
public final class MapRender implements GLSurfaceView.Renderer {
private final static String TAG="地图渲染器";
private final float[] projectionMatrix = new float[16];
private final float[] modelMatrix = new float[16];
private List<Brush> brushes;//绘制任务
public MapRender() {
this.brushes = new ArrayList<>();
}
@Override
public void onSurfaceCreated(GL10 gl10, EGLConfig eglConfig) {
glClearColor(0.0f, 1.0f, 1.0f, 1.0f);
}
@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);
}
//初始化平移矩阵为单位矩阵
setIdentityM(modelMatrix,0);//建立单位矩阵
}
@Override
public void onDrawFrame(GL10 gl10) {
glClear(GL_COLOR_BUFFER_BIT);
//平移支持
//两个矩阵相乘
final float[] temp = new float[16];
multiplyMM(temp, 0, projectionMatrix, 0, modelMatrix, 0);
Log.e(TAG,"重新绘制");
for(int i=0;i<brushes.size();i++){
Brush brush=brushes.get(i);
brush.draw(temp);
}
}
/**
* 添加新的绘制任务
* @param brush 绘制任务
*/
public void addBrush(Brush brush){
brushes.add(brush);
}
/**
* 改变绘图坐标系的偏移值
* @param dx
* @param dy
*/
public void move(float dx, float dy){
translateM(modelMatrix,0,dx,dy,0);//添加平移参数
}
}