转载请注明出处: http://blog.csdn.net/lb377463323/article/details/52136539
上篇文章中介绍了如何使用OpenGL ES2.0绘制三角形,本章将在上篇的基础上进行讲解,另附链接 OpenGL ES2.0入门之Android篇(一)——绘制三角形)
// mMVPMatrix是"Model View Projection Matrix"的缩写
private final float[] mMVPMatrix = new float[16];
private final float[] mProjectionMatrix = new float[16];//定义投影矩阵变量
private final float[] mViewMatrix = new float[16];//定义相机视图矩阵变量
@Override
public void onSurfaceChanged(GL10 unused, int width, int height) {
GLES20.glViewport(0, 0, width, height);
float ratio = (float) width / height;//GLSurfaceView的宽高比
// 根据六个面定义投影矩阵 frustumM(float[] m, int offset, float left, float right, float bottom, float top, float near, float far)
Matrix.frustumM(mProjectionMatrix, 0, -ratio, ratio, -1, 1, 3, 7);
}
投影矩阵在onDrawFrame()方法中使用
Matrix.frustumM请参考Matrix源码
@Override
public void onDrawFrame(GL10 unused) {
...
// 设置相机的位置(视图矩阵)
Matrix.setLookAtM(mViewMatrix, 0, 0, 0, -3, 0f, 0f, 0f, 0f, 1.0f, 0.0f);
// 将mProjectionMatrix和mViewMatrix矩阵相乘并赋给mMVPMatrix
Matrix.multiplyMM(mMVPMatrix, 0, mProjectionMatrix, 0, mViewMatrix, 0);
// 绘制形状
mTriangle.draw(mMVPMatrix);
}
一、修改vertexShaderCode为
public class Triangle {
private final String vertexShaderCode =
"uniform mat4 uMVPMatrix;" +
"attribute vec4 vPosition;" +
"void main() {" +
" gl_Position = uMVPMatrix * vPosition;" +
"}";
private int mMVPMatrixHandle;
...
}
public void draw(float[] mvpMatrix) { // 传递计算出的变换矩阵
...
// 获得形状的变换矩阵的handle
mMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix");
// 把变换矩阵传给着色器
GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, mvpMatrix, 0);
// 绘制三角形
GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, vertexCount);
// 禁用指向三角形的顶点数组
GLES20.glDisableVertexAttribArray(mPositionHandle);
}
此时运行应用程序,它能够按照正确的比例绘制图形,下一步就是添加动作
在MyGlRenderer中添加旋转矩阵代码
private float[] mRotationMatrix = new float[16];
public void onDrawFrame(GL10 gl) {
float[] scratch = new float[16];
...
// 创建旋转矩阵
long time = SystemClock.uptimeMillis() % 4000L;
float angle = 0.090f * ((int) time);
Matrix.setRotateM(mRotationMatrix, 0, angle, 0, 0, -1.0f);
// 将旋转矩阵合并到投影和相机视图变换矩阵中
Matrix.multiplyMM(scratch, 0, mMVPMatrix, 0, mRotationMatrix, 0);
// 绘制三角形
mTriangle.draw(scratch);
}
启用持续渲染
public MyGLSurfaceView(Context context) {
...
// 将下面的代码注释掉
//setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
}
此时运行应用程序,可以观察到图形会一直旋转,下面将展示如何监听用户的触摸事件,让用户旋转一个OpenGL ES对象
1.覆写onTouchEvent()方法
private final float TOUCH_SCALE_FACTOR = 180.0f / 320;
private float mPreviousX;
private float mPreviousY;
@Override
public boolean onTouchEvent(MotionEvent e) {
// 这是Android中的基础知识,这里就不讲解了
float x = e.getX();
float y = e.getY();
switch (e.getAction()) {
case MotionEvent.ACTION_MOVE:
float dx = x - mPreviousX;
float dy = y - mPreviousY;
// 反向旋转至中线以上
if (y > getHeight() / 2) {
dx = dx * -1 ;
}
// 反向旋转至中线左面
if (x < getWidth() / 2) {
dy = dy * -1 ;
}
mRenderer.setAngle(
mRenderer.getAngle() +
((dx + dy) * TOUCH_SCALE_FACTOR));
requestRender();//请求渲染
}
mPreviousX = x;
mPreviousY = y;
return true;
}
2.将setRenderMode的注释去掉
public MyGLSurfaceView(Context context) {
...
// 只有在绘制数据改变时才绘制view
setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
}
3.在MyGlRenderer中将旋转角度暴露出去
public class MyGLRenderer implements GLSurfaceView.Renderer {
...
public volatile float mAngle;
public float getAngle() {
return mAngle;
}
public void setAngle(float angle) {
mAngle = angle;
}
}
4.在onDrawFrame()方法中调用旋转角度
public void onDrawFrame(GL10 gl) {
...
float[] scratch = new float[16];
// 注释掉生成旋转角度的代码
// long time = SystemClock.uptimeMillis() % 4000L;
// float angle = 0.090f * ((int) time);
// 添加mAngle
Matrix.setRotateM(mRotationMatrix, 0, mAngle, 0, 0, -1.0f);
// 合并旋转矩阵到投影和相机视图矩阵
Matrix.multiplyMM(scratch, 0, mMVPMatrix, 0, mRotationMatrix, 0);
// 绘制三角形
mTriangle.draw(scratch);
}
此时运行程序,在屏幕上划动旋转三角形,显示如下图所示:
示例源码:点击下载源码