GLSurfaceView使用之第三篇---三角形的投影模式

这篇博客主要讲解如何使用Android的GLSurfaceView结合OpenGL ES实现图形的投影模式。通过设置投影矩阵,解决设备屏幕非正方形导致的图形比例失真问题,创建并绘制一个等边三角形。同时,文章还涉及了视点设置、颜色缓冲区清理以及顶点数组的使用。
摘要由CSDN通过智能技术生成
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 android.app.Activity;
import android.opengl.GLSurfaceView;
import android.opengl.GLU;
import android.os.Bundle;
import android.util.Log;

public class MainActivity extends Activity {

	private final String TAG = "MainActivity";

	private GLSurfaceView glSurefaceView;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		glSurefaceView = new GLSurfaceView(this);
		glSurefaceView.setRenderer(new GLSurfaceViewRender());
		this.setContentView(glSurefaceView);
	}

	@Override
	protected void onResume() {
		super.onResume();
		glSurefaceView.onResume();
	}

	@Override
	protected void onPause() {
		super.onStop();
		glSurefaceView.onPause();
	}

	class GLSurfaceViewRender implements GLSurfaceView.Renderer {

		@Override
		public void onSurfaceCreated(GL10 gl, EGLConfig config) {
			Log.i(TAG, "onSurfaceCreated");

			// 设置背景颜色
			gl.glClearColor(0.0f, 0f, 0f, 0.5f);
			// 启用顶点数组(否则glDrawArrays不起作用)
			gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
		}

		@Override
		public void onSurfaceChanged(GL10 gl, int width, int height) {
			Log.i(TAG, "onSurfaceChanged");
			// 设置输出屏幕大小
			gl.glViewport(0, 0, width, height);
			/**
			 * Android设备屏幕通常不是正方形的,而OpenGL总是默认地将正方形坐标系投影到这一设备上,这就导致图形无法按真实比例显示。
			 * 要解决这一问题,我们可以使用OpenGL 的投影模式和相机视图将图形的坐标进行转换以适应不同的设备显示。
			 */
			float ratio = (float) width / height;
			gl.glMatrixMode(GL10.GL_PROJECTION); // 设置当前矩阵为投影矩阵
			gl.glLoadIdentity(); // 重置矩阵为初始值
			gl.glFrustumf(-ratio, ratio, -1, 1, 3, 7); // 根据长宽比设置投影矩阵
		}

		private float[] mTriangleArray = {
				// X, Y, Z 这是一个等边三角形
				-0.5f, -0.25f, 0, 0.5f, -0.25f, 0, 0.0f, 0.559016994f, 0 };

		@Override
		public void onDrawFrame(GL10 gl) {
			Log.i(TAG, "onDrawFrame");
			// 清除屏幕和深度缓存(如果不调用该代码, 将不显示glClearColor设置的颜色)
			// 同样如果将该代码放到 onSurfaceCreated 中屏幕会一直闪动
			gl.glClear(GL10.GL_COLOR_BUFFER_BIT);

			/************ 启用MODELVIEW模式,并使用GLU.gluLookAt()来设置视点 ***************/
			// 设置当前矩阵为模型视图模式
			gl.glMatrixMode(GL10.GL_MODELVIEW);
			gl.glLoadIdentity(); // reset the matrix to its default state
			// 设置视点
			GLU.gluLookAt(gl, 0, 0, -5, 0f, 0f, 0f, 0f, 1.0f, 0.0f);
			/*****************************************/

			gl.glColor4f(1.0f, 0.0f, 0.0f, 1.0f);

			FloatBuffer mTriangleBuffer = BufferUtil
					.floatToBuffer(mTriangleArray);
			gl.glVertexPointer(3, GL10.GL_FLOAT, 0, mTriangleBuffer);
			gl.glDrawArrays(GL10.GL_TRIANGLES, 0, 3);
			//
			gl.glLoadIdentity();
			// 平移 (矩阵相乘)
			gl.glTranslatef(-0.2f, 0.3f, 0f);

		}
	}

	static class BufferUtil {
		public static FloatBuffer mBuffer;

		public static FloatBuffer floatToBuffer(float[] a) {
			// 先初始化buffer,数组的长度*4,因为一个float占4个字节
			ByteBuffer mbb = ByteBuffer.allocateDirect(a.length * 4);
			// 数组排序用nativeOrder
			mbb.order(ByteOrder.nativeOrder());
			mBuffer = mbb.asFloatBuffer();
			mBuffer.put(a);
			mBuffer.position(0);
			return mBuffer;
		}
	}
}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值