Android OpenGL与3D应用开发之3D图形绘制

Polygon.java

package cn.MyRenderer;

import android.app.Activity;
import android.opengl.GLSurfaceView;
import android.os.Bundle;

public class Polygon extends Activity{
	public void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);
		GLSurfaceView glView = new GLSurfaceView(this);
		MyRenderer myRender = new MyRenderer();
		glView.setRenderer(myRender);
		setContentView(glView);
	}
}

MyRenderer.java

package cn.MyRenderer;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;

import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;

import android.opengl.GLSurfaceView.Renderer;

public class MyRenderer implements Renderer{

	float[] taperVertices = new float[]{
			0.0f, 0.5f, 0.0f,
			-0.5f, -0.5f, -0.2f,
			0.5f, -0.5f, -0.2f,
			0.0f, -0.2f, 0.2f
	};
	
	int[] taperColors = new int[]{
		65535, 0, 0, 0,
		0, 65535, 0, 0,
		0, 0, 65535, 0,
		65535, 65535, 0, 0
	};
	
	private byte[] taperFacets = new byte[]{
			0,1,2,
			0,1,3,
			1,2,3,
			0,2,3
	};
	
	float[] cubeVertices = new float[]{
		0.5f, 0.5f, 0.5f,
		0.5f, -0.5f, 0.5f,
		-0.5f, -0.5f, 0.5f,
		-0.5f, 0.5f, 0.5f,
		
		0.5f, 0.5f, -0.5f,
		0.5f,-0.5f, -0.5f,
		-0.5f, -0.5f, -0.5f,
		-0.5f, 0.5f, -0.5f
	};
	
	private byte[] cubeFacets = new byte[]{
		0,1,2,
		0,2,3,
		2,3,7,
		2,6,7,
		0,3,7,
		0,4,7,
		4,5,6,
		4,6,7,
		0,1,4,
		1,4,5,
		1,2,6,
		1,5,6
	};
//	float[] triangleData = new float[]{
//			.1f, .6f, .0f,  //上顶点
//			-.3f, .0f, .0f, //左顶点
//			.3f, .1f, .0f   //右顶点
//	};
//	int[] triangleColor = new int[]{
//			65535, 0, 0, 0, //上顶点红色
//			0, 65535, 0, 0, //左顶点绿色
//			0, 0, 65535, 0  //右顶点蓝色
//	};
//	float[] rectData = new float[]{
//			.4f, .4f, .0f,    //右上顶点
//			.4f, -.4f, .0f,   //右下顶点
//			-.4f, .4f, .0f,   //左上顶点
//			-.4f, -.4f, .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[]{
//			-.4f, .4f, .0f,	//左上顶点
//			.4f, .4f, .0f,	//右上顶点
//			.4f, -.4f, .0f,	//右下顶点
//			-.4f, -.4f, .0f	//左下顶点
//	};
//	float[] pentacle = new float[]{
//		.4f, .4f, .0f,
//		-.2f, .3f, .0f,
//		.5f, .0f, .0f,
//		-.4f, .0f, .0f,
//		-.1f, -.3f, .0f
//	};
//	FloatBuffer triangleDataBuffer;
//	IntBuffer triangleColorBuffer;
//	FloatBuffer rectDataBuffer;
//	IntBuffer rectColorBuffer;
//	FloatBuffer rectDataBuffer2;
//	FloatBuffer pentacleBuffer;
//	//控制旋转的角度
//	private float rotate;
	
	FloatBuffer taperVerticesBuffer;
	IntBuffer taperColorsBuffer;
	ByteBuffer taperFacetsBuffer;
	FloatBuffer cubeVerticesBuffer;
	ByteBuffer cubeFacetsBuffer;
	
	private float rotate;
	
	public MyRenderer()
	{
		taperVerticesBuffer = floatBufferUtil(taperVertices);
		taperFacetsBuffer = ByteBuffer.wrap(taperFacets);
		taperColorsBuffer = intBufferUtil(taperColors);
		cubeVerticesBuffer = floatBufferUtil(cubeVertices);
		cubeFacetsBuffer = ByteBuffer.wrap(cubeFacets);
		
		//将顶点位置数据数组转换成FloatBuffer
//		triangleDataBuffer = floatBufferUtil(triangleData);
//		rectDataBuffer = floatBufferUtil(rectData);
//		rectDataBuffer2 = floatBufferUtil(rectData2);
//		pentacleBuffer = floatBufferUtil(pentacle);
//		//将顶点颜色数据数组转换成IntBuffer
//		triangleColorBuffer = intBufferUtil(triangleColor);
//		rectColorBuffer = intBufferUtil(rectColor);
	}
	
	@Override
	public void onSurfaceCreated(GL10 gl, EGLConfig config) {
		// TODO Auto-generated method stub
		// 关闭抗抖动
		gl.glDisable(GL10.GL_DITHER);	//可提高性能
		//设置系统对透视进行修正
		gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_FASTEST);
		gl.glClearColor(0, 0, 0, 0);	//ClearColor(float red, float green, float blue, float alpha)
		//设置阴影平滑模式
		gl.glShadeModel(GL10.GL_SMOOTH);
		//启用深度测试
		/*
		 * 让OpenGL ES负责跟踪每个物体在Z轴上的深度,
		 * 这样就可以避免后面的无图遮挡前面的物体 
		*/
		gl.glEnable(GL10.GL_DEPTH_TEST);
		//设置深度测试的类型
		gl.glDepthFunc(GL10.GL_LEQUAL);
	}
	
	/*
	 * 初始化3D场景
	 */
	@Override
	public void onSurfaceChanged(GL10 gl, int width, int height) {
		// TODO Auto-generated method stub
		//设置3D视窗的大小及位置(前两参数为视窗位置,后两参数为视窗宽、高)
		gl.glViewport(0, 0, width, height);
		//将当前矩阵模式设为投影矩阵
		gl.glMatrixMode(GL10.GL_PROJECTION);
		//初始化单位矩阵
		gl.glLoadIdentity();
		//计算透视窗的宽度、高度比
		float ratio = (float) width / height;
		//调用此方法设置透视窗的空间大小
		/*
		 * 前两个参数用于设置X轴上的最小和最大坐标值,
		 * 中间两个参数用于设置Y轴上的最小和最大坐标值,
		 * 最后两个参数用于设置Z轴上所能绘制的场景的深
		 * 度的最小和最大值。
		*/
		gl.glFrustumf(-ratio, ratio, -1, 1, 1, 10);
	}
	
	//绘制图形的方法
	@Override
	public void onDrawFrame(GL10 gl) {
		// TODO Auto-generated method stub
		//清除屏幕缓存和深度缓存
		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);
		
		//---------------------绘制第一个3d图形-----------------------
		gl.glLoadIdentity();
		gl.glTranslatef(-0.6f, 0.0f, -1.5f);
		gl.glRotatef(rotate, 0f, 0.2f, 0f);
		gl.glVertexPointer(3, GL10.GL_FLOAT, 0, taperVerticesBuffer);
		//设置顶点的颜色数据
		gl.glColorPointer(4, GL10.GL_FIXED, 0, taperColorsBuffer);
		gl.glDrawElements(GL10.GL_TRIANGLE_STRIP, taperFacetsBuffer.remaining(), GL10.GL_UNSIGNED_BYTE, taperFacetsBuffer);
		
		//---------------------绘制第二个3d图形-----------------------
		gl.glLoadIdentity();
		gl.glTranslatef(0.7f, 0.0f, -2.2f);
		gl.glRotatef(rotate, 0f, 0.2f, 0f);
		gl.glRotatef(rotate, 1f, 0f, 0f);
		
		gl.glVertexPointer(3, GL10.GL_FLOAT, 0, cubeVerticesBuffer);
		gl.glDrawElements(GL10.GL_TRIANGLE_STRIP, cubeFacetsBuffer.remaining(), GL10.GL_UNSIGNED_BYTE, cubeFacetsBuffer);
		gl.glFinish();
		gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
		rotate+=1;
		
		
		
		//---------------------绘制第一个2d图形-----------------------
		//重置当前的模型视图矩阵
//		gl.glLoadIdentity();
//		gl.glTranslatef(-.32f, .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);
//		//---------------------绘制第二个2d图形-----------------------
//		//重置当前的模型视图矩阵
//		gl.glLoadIdentity();
//		gl.glTranslatef(.6f, .8f, -1.5f);
//		gl.glRotatef(rotate, 0f, 0f, 0.1f);
//		//设置顶点的位置数据
//		gl.glVertexPointer(3, GL10.GL_FLOAT, 0, rectDataBuffer);
//		//设置顶点的颜色数据
//		gl.glColorPointer(4, GL10.GL_FIXED, 0, rectDataBuffer);
//		//根据顶点数据绘制平面图形
//		gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4);
//		//---------------------绘制第三个2d图形-----------------------
//		//重置当前的模型视图矩阵
//		gl.glLoadIdentity();
//		gl.glTranslatef(-.4f, -.5f, -1.5f);
//		gl.glRotatef(rotate, 0f, 0.2f, 0f);
//		//设置顶点的位置数据(依然使用之前的顶点颜色)
//		gl.glVertexPointer(3, GL10.GL_FLOAT, 0, rectDataBuffer2);
//		//根据顶点数据绘制平面图形
//		gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4);
//		//---------------------绘制第四个2d图形-----------------------
//		//重置当前的模型视图矩阵
//		gl.glLoadIdentity();
//		gl.glTranslatef(.4f, -.5f, -1.5f);
//		//设置使用纯色填充
//		gl.glColor4f(1.0f, .2f, .2f, .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);
//		rotate+=1;
	}
	
	//定义一个工具方法,将int[]数组转换为OpenGl ES所需的IntBuffer
	private IntBuffer intBufferUtil(int[] arr)
	{
		IntBuffer mBuffer;
		//初始化ByteBuffer,长度为arr数组的长度*4,因为一个int占4个字节
		ByteBuffer qbb = ByteBuffer.allocateDirect(arr.length * 4);
		//数组排列用nativeOrder
		qbb.order(ByteOrder.nativeOrder());
		mBuffer = qbb.asIntBuffer();
		mBuffer.put(arr);
		mBuffer.position(0);
		return mBuffer;
	}
	//定义一个工具方法,将float[]数组转换为OpenGL ES所需的FloatBuffer
	private FloatBuffer floatBufferUtil(float[] arr)
	{
		FloatBuffer mBuffer;
		//初始化ByteBuffer,长度为arr数组的长度*4,因为一个int占4个字节
		ByteBuffer qbb = ByteBuffer.allocateDirect(arr.length * 4);
		//数组排列用nativeOrder
		qbb.order(ByteOrder.nativeOrder());
		mBuffer = qbb.asFloatBuffer();
		mBuffer.put(arr);
		mBuffer.position(0);
		return mBuffer;
	}

}

以上代码中注释部分包含2D图形的绘制

3D图形绘制代码运行截图:

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值