Android之GLES2.0画三角形测试代码

public class MainActivity extends Activity {

	private MyTDView myTDView;
	
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //设置界面显示为竖屏
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
        myTDView = new MyTDView(this);
        myTDView.requestFocus();
        myTDView.setFocusableInTouchMode(true);
        setContentView(myTDView);
    }
    
    @Override
    public void onResume() {
    	super.onResume();
    	myTDView.onResume();
    }
    
    @Override
    public void onPause() {
    	super.onPause();
    	myTDView.onPause();
    }
}

class MyTDView extends GLSurfaceView {
	public static float[] mProjMatrix = new float[16];	//4 * 4 投影矩阵
	public static float[] mVMatrix = new float[16];		//摄影机位置朝向参数矩阵
	public static float[] mMVPMatrix;					//最后起作用的总变换矩阵
	
	int mProgram;										//自定义渲染管线着色程序id
	int muMVPMatrixHandle;								//总变换矩阵的引用
	int maPositionHandle;								//顶点位置属性引用
	int maColorHandle;									//顶点颜色属性引用
							
	static float[] mMMatrix = new float[16];			//具体物体的3D变换矩阵, 包括旋转, 平移, 缩放
	FloatBuffer mVertexBuffer;							//顶点坐标数据缓冲
	FloatBuffer mColorBuffer;							//顶点着色数据缓冲
	
	float xAngle = 0;									//绕x轴旋转角度
	Context context;
	private SceneRenderer mSceneRender;	
	public MyTDView(Context context) {
		super(context);
		this.context = context;
		//设置OpenGLES版本为2.0
		this.setEGLContextClientVersion(2);	
		mSceneRender = new SceneRenderer();
		this.setRenderer(mSceneRender);
		this.setRenderMode(GLSurfaceView.RENDERMODE_CONTINUOUSLY);
	}

	private class SceneRenderer implements Renderer{
		
		@Override
		public void onSurfaceCreated(GL10 gl, EGLConfig config) {
			GLES20.glClearColor(0, 0, 0, 1.0f);
			float vertices[] = new float[]{
					-0.8f, 0 , 0,	//第1个点位置:x轴左边的坐标 
					0, -0.8f, 0,	//第2个点位置:y轴坐标
					0.8f, 0, 0		//第3个点位置:x轴右边的坐标
			};
			ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length * 4);
			vbb.order(ByteOrder.nativeOrder());
			mVertexBuffer = vbb.asFloatBuffer();
			mVertexBuffer.put(vertices);
			mVertexBuffer.position(0);
			
			float colors[] = {
					1, 0, 0, 0,//红色
					0, 1, 0, 0,//绿色
					0, 0, 1, 0 //蓝色
			};
			ByteBuffer cbb = ByteBuffer.allocateDirect(colors.length * 4);
			cbb.order(ByteOrder.nativeOrder());
			mColorBuffer = cbb.asFloatBuffer();
			mColorBuffer.put(colors);
			mColorBuffer.position(0);
			
			//加载着色器程序
//			String mVertexShaderCode = ShaderUtil.loadFromAssetsFile("vertex.sh", context.getResources());
//			String mFragmentShaderCode = ShaderUtil.loadFromAssetsFile("frag.sh", context.getResources());
			
			String mVertexShaderCode =	"uniform mat4 uMVPMatrix;"+ 
										"attribute vec3 aPosition;"+ 
										"attribute vec4 aColor;"+ 
										"varying  vec4 vColor;"+ 
										"void main(){"+                            		
										"	gl_Position = uMVPMatrix * vec4(aPosition,1);"+ 
										"	vColor = aColor;"+
										"}";							
			String mFragmentShaderCode ="precision mediump float;"+
										"varying  vec4 vColor;"+ 
										"void main(){"+                       
										"	gl_FragColor = vColor;"+
										"}";	
			mProgram = ShaderUtil.loadCompileRunProgram(mVertexShaderCode, mFragmentShaderCode);
			//获得着色器程序相关变量操作句柄
			maPositionHandle = GLES20.glGetAttribLocation(mProgram, "aPosition");
			maColorHandle = GLES20.glGetAttribLocation(mProgram, "aColor");
			muMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix");
			
			GLES20.glEnable(GLES20.GL_DEPTH_TEST);
		}

		@Override
		public void onSurfaceChanged(GL10 gl, int width, int height) {
			GLES20.glViewport(0, 0, width, height);
			float ratio = (float)width/height;
			Matrix.frustumM(mProjMatrix, 0, -ratio, ratio, -1, 1, 1, 10);
			Matrix.setLookAtM(mVMatrix, 0, 0f,0f,3f,0f,0f,0f,0f,1.0f,0.0f);
		}

		@Override
		public void onDrawFrame(GL10 gl) {
			GLES20.glClear(GLES20.GL_DEPTH_BUFFER_BIT | GLES20.GL_COLOR_BUFFER_BIT);
			GLES20.glUseProgram(mProgram);
			Matrix.setRotateM(mMMatrix, 0, 0, 0, 1, 0);
			Matrix.translateM(mMMatrix, 0, 0, 0, 1);
			Matrix.rotateM(mMMatrix, 0, xAngle, 1, 0, 0);
			
			mMVPMatrix = new float[16];
			Matrix.multiplyMM(mMVPMatrix, 0, mVMatrix, 0, mMMatrix, 0);
			Matrix.multiplyMM(mMVPMatrix, 0, mProjMatrix, 0, mMVPMatrix, 0);

			GLES20.glUniformMatrix4fv(muMVPMatrixHandle, 1, false, mMVPMatrix, 0);
			GLES20.glVertexAttribPointer(maPositionHandle, 3, GLES20.GL_FLOAT, false, 3 * 4, mVertexBuffer);
			GLES20.glVertexAttribPointer(maColorHandle, 4, GLES20.GL_FLOAT, false, 4 * 4, mColorBuffer);

			GLES20.glEnableVertexAttribArray(maPositionHandle);
			GLES20.glEnableVertexAttribArray(maColorHandle);
			
			GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, 3);//3个顶点
			xAngle = xAngle + 0.3f;
		}
	}
}

class ShaderUtil {
	
	public static int loadCompileShader(int shaderType , String source){
		int shader = GLES20.glCreateShader(shaderType);
		if(shader == 0) return 0;
		GLES20.glShaderSource(shader, source);
		GLES20.glCompileShader(shader);
		int[] compiled = new int[1];
		GLES20.glGetShaderiv(shader, GLES20.GL_COMPILE_STATUS, compiled, 0);
		if(compiled[0] == 0){
             Log.e("ES20_ERROR", "编译程序"+shaderType+":"+GLES20.glGetShaderInfoLog(shader));
             GLES20.glDeleteShader(shader);
             shader = 0;
		}
		return shader;
	}
	
	public static void checkGLError(String op){
		int error;
		while( (error = GLES20.glGetError()) != GLES20.GL_NO_ERROR ){
			 Log.e("ES20_ERROR", op + ": glError " + error);
	         throw new RuntimeException(op + ": glError " + error);
		}
	}
	
	public static int loadCompileRunProgram(String vertexCode , String fragmentCode){
		int vertexShader = loadCompileShader(GLES20.GL_VERTEX_SHADER, vertexCode);
		if(vertexShader == 0)	return 0;
		int fragShader = loadCompileShader(GLES20.GL_FRAGMENT_SHADER, fragmentCode);
		if(fragShader == 0)	return 0;
		int program = GLES20.glCreateProgram();
		if(program == 0)	return 0;
		
		GLES20.glAttachShader(program, vertexShader);
		checkGLError("glAttachShader");
		GLES20.glAttachShader(program, fragShader);
		checkGLError("glAttachShader");
		
		GLES20.glLinkProgram(program);
		int[] linkStatus = new int[1];
		GLES20.glGetProgramiv(program, GLES20.GL_LINK_STATUS, linkStatus, 0);
		if(linkStatus[0] != GLES20.GL_TRUE){
			Log.e("ES20.ERROR", "链接程序: "+GLES20.glGetProgramInfoLog(program));
			GLES20.glDeleteProgram(program);
			program = 0;
		}			
		return program;
	}
	
	public static String loadFromAssetsFile(String fileName, Resources resources){
		String result = null;
		try {
			InputStream is = resources.getAssets().open(fileName);
			int ch = 0;
			ByteArrayOutputStream baos = new ByteArrayOutputStream();
			while((ch = is.read()) != -1){
				baos.write(ch);
			}
			byte[] buffer = baos.toByteArray();
			baos.close();
			is.close();
			result = new String(buffer, "UTF-8");
			result = result.replaceAll("\\r\\n", "\n");
		} catch (Exception e) {
			e.printStackTrace();
		}
		return result;
	}
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值