初学Android,OpenGL ES之绘制平面多边形(八十)

时间:2022-05-19 03:54:05

在Android中使用OpenGL ES需三步

1.创建GLSurfaceView组件,使用Activity显示GLSurfaceView组件

2.为GLSurfaceView创建GLSurfaceView.Renderer实例,实现Renderer类时需要实现接口里的三个方法

     void onDrawFrame(GL10 gl)  Renderer对象调用此方法绘制GLSurfaceView的当前帧

     void onSurfaceChanged(GL10 gl, int width, int height) GLSurfaceView的大小改变时回调方法

    void onSurfaceCreated(GL10 gl, EGLConfig config)      GLSurfaceView创建时回调此方法

上面的参数GL10,相当于是Android 2D绘图中的Canvas,GL10就是绘制图形的画笔


绘制2D图形的步骤基本都是调用GL10的方法

1.调用glEnableClientState(GL10.GL_VERTEX_ARRAY); 启用顶点座标数据

2.调用glEnableClientState(GL10.GL_COLOR_ARRAY);  启用顶点颜色数据

3.调用glVertexPointer(int size, int type, int stride, Buffer pointer); 设置位置顶点数据

     参数size,指定多少个元素指定一个顶点位置,通常是3(x,y,z三轴坐标),参数type表示坐标数据类型,可以是整型或浮点型,

 pointer是一个一维数组,格式为(x1,y1,z1,x2,y2,z2......xN,yN,xN),按顺序每三个为一组代表一个顶点的x,y,z的坐标

4.调用glVertexPointer(int size, int type, int stride, Buffer pointer); 

    参数跟glVertexPointer差不多,只是pointer是4个为一组指定顶点的颜色,分别是红,绿,蓝,透明度的值

5.调用glDrawArrays(int mode, int first, int count) 绘制平面

    第一个参数指定绘制图形类型,第二个参数指定从哪个顶点开始绘制,第三个参数指定总共绘制的顶点数


下面是一个例子

初学Android,OpenGL ES之绘制平面多边形(八十)

先定义一个Renderer

public class MyRenderer implements Renderer {
	float[] triangleData = new float[] { 0.1f, 0.6f, 0.0f, // 上顶点
			-0.3f, 0.0f, 0.0f, // 左顶点
			0.3f, 0.1f, 0.0f // 右顶点
	};
	int[] triangleColor = new int[] { 65535, 0, 0, 0, // 上顶点红色
			0, 65535, 0, 0, // 左顶点绿色
			0, 0, 65535, 0 // 右顶点蓝色
	};
	float[] rectData = new float[] { 0.4f, 0.4f, 0.0f, // 右上顶点
			0.4f, -0.4f, 0.0f, // 右下顶点
			-0.4f, 0.4f, 0.0f, // 左上顶点
			-0.4f, -0.4f, 0.0f // 左下顶点
	};
	int[] rectColor = new int[] { 0, 65535, 0, 0, // 右上顶点绿色
			0, 0, 65535, 0, // 右下顶点蓝色
			65535, 0, 0, 0, // 左上顶点红色
			65535, 65535, 0, 0 // 左下顶点黄色
	};
	// 依然是正方形的四个顶点,只是顺序交换了一下
	float[] rectData2 = new float[] { -0.4f, 0.4f, 0.0f, // 左上顶点
			0.4f, 0.4f, 0.0f, // 右上顶点
			0.4f, -0.4f, 0.0f, // 右下顶点
			-0.4f, -0.4f, 0.0f // 左下顶点
	};
	float[] pentacle = new float[] { 0.4f, 0.4f, 0.0f, -0.2f, 0.3f, 0.0f, 0.5f,
			0.0f, 0f, -0.4f, 0.0f, 0f, -0.1f, -0.3f, 0f };

	FloatBuffer triangleDataBuffer;
	IntBuffer triangleColorBuffer;
	FloatBuffer rectDataBuffer;
	IntBuffer rectColorBuffer;
	FloatBuffer rectDataBuffer2;
	FloatBuffer pentacleBuffer;

	public MyRenderer() {
		// 将顶点位置数据数组包装成FloatBuffer;
		triangleDataBuffer = FloatBuffer.wrap(triangleData);
		rectDataBuffer = FloatBuffer.wrap(rectData);
		rectDataBuffer2 = FloatBuffer.wrap(rectData2);
		pentacleBuffer = FloatBuffer.wrap(pentacle);
		// 将顶点颜色数据数组包装成IntBuffer;
		triangleColorBuffer = IntBuffer.wrap(triangleColor);
		rectColorBuffer = IntBuffer.wrap(rectColor);
	}

	@Override
	public void onSurfaceCreated(GL10 gl, EGLConfig config) {
		// 关闭抗抖动
		gl.glDisable(GL10.GL_DITHER);
		// 设置系统对透视进行修正
		gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_FASTEST);
		gl.glClearColor(0, 0, 0, 0);
		// 设置阴影平滑模式
		gl.glShadeModel(GL10.GL_SMOOTH);
		// 启用深度测试
		gl.glEnable(GL10.GL_DEPTH_TEST);
		// 设置深度测试的类型
		gl.glDepthFunc(GL10.GL_LEQUAL);
	}

	@Override
	public void onSurfaceChanged(GL10 gl, int width, int height) {
		// 设置3D视窗的大小及位置
		gl.glViewport(0, 0, width, height);
		// 将当前矩阵模式设为投影矩阵
		gl.glMatrixMode(GL10.GL_PROJECTION);
		// 初始化单位矩阵
		gl.glLoadIdentity();
		// 计算透视视窗的宽度、高度比
		float ratio = (float) width / height;
		// 调用此方法设置透视视窗的空间大小。
		gl.glFrustumf(-ratio, ratio, -1, 1, 1, 10);
	}

	// 绘制图形的方法
	@Override
	public void onDrawFrame(GL10 gl) {
		// 清除屏幕缓存和深度缓存
		gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
		// 启用顶点座标数据
		gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
		// 启用顶点颜色数据
		gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
		// 设置当前矩阵堆栈为模型堆栈,
		gl.glMatrixMode(GL10.GL_MODELVIEW);
		// --------------------绘制第一个图形---------------------
		// 重置当前的模型视图矩阵
		gl.glLoadIdentity();
		gl.glTranslatef(-0.32f, 0.35f, -1f);
		// 设置顶点的位置数据
		gl.glVertexPointer(3, GL10.GL_FLOAT, 0, triangleDataBuffer);
		// 设置顶点的颜色数据
		gl.glColorPointer(4, GL10.GL_FIXED, 0, triangleColorBuffer);
		// 根据顶点数据绘制平面图形
		gl.glDrawArrays(GL10.GL_TRIANGLES, 0, 3);
		// --------------------绘制第二个图形---------------------
		// 重置当前的模型视图矩阵
		gl.glLoadIdentity();
		gl.glTranslatef(0.6f, 0.8f, -1.5f);
		// 设置顶点的位置数据
		gl.glVertexPointer(3, GL10.GL_FLOAT, 0, rectDataBuffer);
		// 设置顶点的颜色数据
		gl.glColorPointer(4, GL10.GL_FIXED, 0, rectColorBuffer);
		// 根据顶点数据绘制平面图形
		gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4);
		// --------------------绘制第3个图形---------------------
		// 重置当前的模型视图矩阵
		gl.glLoadIdentity();
		gl.glTranslatef(-0.4f, -0.5f, -1.5f);
		// 设置顶点的位置数据(依然使用之前的顶点颜色)
		gl.glVertexPointer(3, GL10.GL_FLOAT, 0, rectDataBuffer2);
		// 根据顶点数据绘制平面图形
		gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4);
		// --------------------绘制第4个图形---------------------
		// 重置当前的模型视图矩阵
		gl.glLoadIdentity();
		gl.glTranslatef(0.4f, -0.5f, -1.5f);
		// 设置使用纯色填充
		gl.glColor4f(1.0f, 0.2f, 0.2f, 0.0f);
		gl.glDisableClientState(GL10.GL_COLOR_ARRAY);
		// 设置顶点的位置数据
		gl.glVertexPointer(3, GL10.GL_FLOAT, 0, pentacleBuffer);
		// 根据顶点数据绘制平面图形
		gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 5);
		// 绘制结束
		gl.glFinish();
		gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
	}
}
再到Activity中使用此Renderer

public class Polygon extends Activity {
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		// 创建一个GLSurfaceView,用于显示OpenGL绘制的图形
		GLSurfaceView glView = new GLSurfaceView(this);
		// 创建GLSurfaceView的内容绘制器
		MyRenderer myRender = new MyRenderer();
		// 为GLSurfaceView设置绘制器
		glView.setRenderer(myRender);
		setContentView(glView);
	}
}