第3.3.4节 创建高级图形之OpenGL(三)

Android视图框架对于创建复杂布局非常方便。然而,这种便利是以性能为代价的。当性能至关重要的时候,Android提供了几种更强大的图形处理能力,当然难度也是随之上升了。在本节中,我将介绍:

(1)SurfaceView使用标准的Canvas对象并与单独的渲染进程结合,得到更好的性能;

(2)新得RenderScript框架可以被用于创建独立结构的图形渲染;

(3)OpenGL可用于一些严格的图形工作和游戏。

3、OpenGL可用于一些严格的图形工作和游戏

Android为使用OpenGL ES 1.0和OpenGL ES 2.0标准的硬件渲染图形提供了完全支持。OpenGL API可以通过Java框架和本地开发套件(NDK)来进行调用。Java框架提供了一个简单已用的API,但是却有一个小的性能损失。对于全加速图形支持,以及移植现有代码,NDK提供了最佳的解决方案。不过,这超出了本书的范围。

这里我只做一个java框架的API,初步了解OpenGL。创建OpenGL需要两个类:GLSurfaceView和GLSurface.Render。GLSurfaceView类和SurfaceView类相似,并且可以结合OpenGL渲染图形和Android标准视图框架。这个类提供了单独的渲染线程,可以独立于UI线程生成图形。此外,GLSurfaceView提供了一些调试工具,可以来帮助在渲染代码中追踪错误。

注意:OpenGL,需要一部android设备,模拟器是不可用的。

效果如下图:

一个不停旋转的三角形,当手触摸屏幕的时候,背景颜色会随着手触碰的位置不通而变化。

这里分为三部:

3.1 声明GLSurface.Render方法

public class ExampleRender implements GLSurfaceView.Renderer {

	private float[] mVertics={-2.0f, -2.0f, 0,  2.0f, -2.0f, 0,  0.0f, 2.0f, 0};
	private FloatBuffer mVertexBuffer;
	private float mRed;
	private float mGreen;
	private float mBlue;
	private float mAngle;
	private long mLastFrameTime = 0;
	/**********************************************************
	 * 更新onDrawFrame方法,基于color字段设置视图的颜色并绘制三角形。
	 */
	@Override
	public void onDrawFrame(GL10 gl) {
		// TODO Auto-generated method stub
		gl.glClearColor(mRed, mGreen, mBlue, 1.0f);
		gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
		upDateAngle();
		gl.glLoadIdentity();
		gl.glTranslatef(0.0f, 0.0f, -7.0f);
		gl.glRotatef(mAngle, 0.0f, 0.0f, 1.0f);
		gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
		gl.glColor4f(255f, 255f, 255f, 0.0f);
		gl.glVertexPointer(3, GL10.GL_FLOAT, 0, mVertexBuffer);
		gl.glDrawArrays(GL10.GL_TRIANGLES, 0, 3);
		gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
	}
	/***********************************************************
	 * 更新onSurfaceChanged方法来设置映射矩阵。OpenGL假定了一个方形的
	 * 显示,所以你需要改变图形的长度比来匹配屏幕。
	 */
	@Override
	public void onSurfaceChanged(GL10 gl, int width, int height) {
		// TODO Auto-generated method stub
		gl.glViewport(0, 0, width, height);
		gl.glMatrixMode(GL10.GL_PROJECTION);
		gl.glLoadIdentity();
		float ratio = (float)width/height;
		GLU.gluPerspective(gl, 45.0f, ratio, 0.1f, 100.0f);
		gl.glMatrixMode(GL10.GL_MODELVIEW);
		gl.glLoadIdentity();
	}
	/***********************************************************
	 * 初始化方法中的顶点
	 */
	@Override
	public void onSurfaceCreated(GL10 gl, EGLConfig config) {
		// TODO Auto-generated method stub
		ByteBuffer vertexByteBuffer = ByteBuffer.allocateDirect(mVertics.length*4);
		vertexByteBuffer.order(ByteOrder.nativeOrder());
		mVertexBuffer = vertexByteBuffer.asFloatBuffer();
		mVertexBuffer.put(mVertics);
		mVertexBuffer.position(0);
	}	
	private void upDateAngle(){
		long now = System.currentTimeMillis();
		if(mLastFrameTime != 0){
			mAngle += 10*(now - mLastFrameTime)/1000.0;
		}
		mLastFrameTime = now;
	}	
	public void setColor(float red, float green, float blue){
		this.mRed = red;
		this.mGreen = green;
		this.mBlue = blue;
	}
}

这里重载了GLSurfaceView的创建,更改,和onDrawFrame方法,并添加了,更新角度和设置颜色的方法,方便我们使用。

3.2 继承GLSurfaceView方法,setRender为3.1中的ExampleRender

public class ExampleGLSurfaceView extends GLSurfaceView {

	public ExampleRender mRender;
	public ExampleGLSurfaceView(Context context) {
		super(context);
		// TODO Auto-generated constructor stub
		mRender = new ExampleRender();
		setRenderer(mRender);
	}
	
	/***************************************************
	 * 重写onTouchEvent
	 */
	@Override
	public boolean onTouchEvent(MotionEvent event){
		switch (event.getAction()){
		case MotionEvent.ACTION_DOWN:
		case MotionEvent.ACTION_MOVE:
			final float x = event.getX()/getWidth();
			final float y = event.getY()/getHeight();
			queueEvent(new Runnable(){

				@Override
				public void run() {
					// TODO Auto-generated method stub
					mRender.setColor(x, y, 0.5f);
				}
				
			});
			return true;
		}
		return super.onTouchEvent(event);		
	}
}

这里重写了onTouchEvent方法,实现了手触碰,颜色变化的功能。

3.3 在主界面上显示当前做的View

public class MainActivity extends Activity {

	private ExampleGLSurfaceView mGLView;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		mGLView = new ExampleGLSurfaceView(this);
		requestWindowFeature(Window.FEATURE_NO_TITLE);
		setContentView(mGLView);
	}

这里是使用了java的框架的API,也只是实现了一个小的功能,OpenGL的功能非常的强大,大家可以参考http://blog.csdn.net/mapdigit/article/details/7526556目录列表来学习。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值