Android 3D opengl 立方体 多纹理

最近学习 opengl,看了一些简单的教程。发现一般都是到实现金字塔或者立方体就结束了。

纹理方面,对三维物体的多个面未做处理。参看了这些例子,做一个android 上的多纹理的立方体。

效果图:

1.

立方体效果图

2.

立方体效果图2

以下是主要代码:

Activity负责初始化相关资源文件。重写了onTouchEvent()方法,实现鼠标翻转,方便观察。

public class Cube extends Activity {
	
    GLRender render = new GLRender();
	
    private float mPreviousX;
    private float mPreviousY;
    private final float TOUCH_SCALE_FACTOR = 180.0f / 320;
    private final float TRACKBALL_SCALE_FACTOR = 36.0f;
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
    	super.onCreate(savedInstanceState);
		GLImage.load(this.getResources());
		GLSurfaceView glView = new GLSurfaceView(this);
		
		glView.setRenderer(render);
		setContentView(glView);
    }
    public boolean onKeyUp(int keyCode, KeyEvent event)
	{
		render.onKeyUp(keyCode, event);
		return false;
	}
	 public boolean onTrackballEvent(MotionEvent e) {
		 render.xrot += e.getX() * TRACKBALL_SCALE_FACTOR;
		 render.yrot += e.getY() * TRACKBALL_SCALE_FACTOR;
	        return true;
	    }
		 public boolean onTouchEvent(MotionEvent e) {
	        float x = e.getX();
	        float y = e.getY();
	        switch (e.getAction()) {
	        case MotionEvent.ACTION_MOVE:
	            float dx = x - mPreviousX;
	            float dy = y - mPreviousY;
	            render.xrot += dx * TOUCH_SCALE_FACTOR;
	            render.yrot += dy * TOUCH_SCALE_FACTOR;
	        }
	        mPreviousX = x;
	        mPreviousY = y;
	        return true;
	    }
}
class GLImage
{	
	public static Bitmap mBitmap1;
	public static Bitmap mBitmap2;
	public static Bitmap mBitmap3;
	public static Bitmap mBitmap4;
	public static Bitmap mBitmap5;
	public static Bitmap mBitmap6;
	public static void load(Resources resources)
	{
		mBitmap1 = BitmapFactory.decodeResource(resources, R.drawable.icon1);
		mBitmap2 = BitmapFactory.decodeResource(resources, R.drawable.icon2);
		mBitmap3 = BitmapFactory.decodeResource(resources, R.drawable.icon3);
		mBitmap4 = BitmapFactory.decodeResource(resources, R.drawable.icon4);
		mBitmap5 = BitmapFactory.decodeResource(resources, R.drawable.icon5);
		mBitmap6 = BitmapFactory.decodeResource(resources, R.drawable.icon6);
		
	}
}


 

Render负责opengl实体的初始化以及配置、画出等,相关光源,观察模型方面没有深入。

 

public class GLRender implements Renderer
{
	boolean key = true;
	float xrot = 0.0f;
	float yrot = 0.0f;
	float xspeed, yspeed;
	float z = -5.0f;
	int one = 0x10000;
	
	//光线参数
	FloatBuffer lightAmbient = FloatBuffer.wrap(new float[]{0.5f,0.5f,0.5f,1.0f}); 
	FloatBuffer lightDiffuse = FloatBuffer.wrap(new float[]{1.0f,1.0f,1.0f,1.0f}); 
	FloatBuffer lightPosition = FloatBuffer.wrap(new float[]{0.0f,0.0f,2.0f,1.0f}); 
	
	int [] texture;
	
	IntBuffer vertices = IntBuffer.wrap(new int[]{
			-one,-one,one,
			one,-one,one,
			one,one,one,
			-one,one,one,
			
			-one,-one,-one,
			-one,one,-one,
			one,one,-one,
			one,-one,-one,
			
			-one,one,-one,
			-one,one,one,
			one,one,one,
			one,one,-one,
			
			-one,-one,-one,
			one,-one,-one,
			one,-one,one,
			-one,-one,one,
			
			one,-one,-one,
			one,one,-one,
			one,one,one,
			one,-one,one,
			
			-one,-one,-one,
			-one,-one,one,
			-one,one,one,
			-one,one,-one,
			
	});
	
	IntBuffer normals = IntBuffer.wrap(new int[]{
			0,0,one,
			0,0,one,
			0,0,one,
			0,0,one,
			
			0,0,one,
			0,0,one,
			0,0,one,
			0,0,one,
			
			0,one,0,
			0,one,0,
			0,one,0,
			0,one,0,
			
			0,-one,0,
			0,-one,0,
			0,-one,0,
			0,-one,0,
			
			one,0,0,
			one,0,0,
			one,0,0,
			one,0,0,
			
			-one,0,0,
			-one,0,0,
			-one,0,0,
			-one,0,0,
	});
	
	IntBuffer texCoords = IntBuffer.wrap(new int[]{
		one,0,0,0,0,one,one,one,	
		0,0,0,one,one,one,one,0,
		one,one,one,0,0,0,0,one,
		0,one,one,one,one,0,0,0,
		0,0,0,one,one,one,one,0,
		one,0,0,0,0,one,one,one,
	});
	ByteBuffer indices1 = ByteBuffer.wrap(new byte[]{
			0,1,3,2,
			0,0,0,0,
			0,0,0,0,
			0,0,0,0,
			0,0,0,0,
			0,0,0,0,
	});
	ByteBuffer indices2 = ByteBuffer.wrap(new byte[]{
			0,0,0,0,
			4,5,7,6,
			0,0,0,0,
			0,0,0,0,
			0,0,0,0,
			0,0,0,0,
	});
	ByteBuffer indices3 = ByteBuffer.wrap(new byte[]{
			0,0,0,0,
			0,0,0,0,
			8,9,11,10,
			0,0,0,0,
			0,0,0,0,
			0,0,0,0,
	});
	ByteBuffer indices4 = ByteBuffer.wrap(new byte[]{
			0,0,0,0,
			0,0,0,0,
			0,0,0,0,
			12,13,15,14,
			0,0,0,0,
			0,0,0,0,
	});
	ByteBuffer indices5 = ByteBuffer.wrap(new byte[]{
			0,0,0,0,
			0,0,0,0,
			0,0,0,0,
			0,0,0,0,
			16,17,19,18,
			0,0,0,0,
	});
	ByteBuffer indices6 = ByteBuffer.wrap(new byte[]{
			0,0,0,0,
			0,0,0,0,
			0,0,0,0,
			0,0,0,0,
			0,0,0,0,
			20,21,23,22,
	});
	
	@Override
	public void onDrawFrame(GL10 gl)
	{
		// 清除屏幕和深度缓存
		gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
		
		gl.glMatrixMode(GL10.GL_MODELVIEW);
		// 重置当前的模型观察矩阵
		gl.glLoadIdentity();
		
		gl.glEnable(GL10.GL_LIGHTING);
		
		
		gl.glTranslatef(0.0f, 0.0f, z);
		
		//设置旋转
		gl.glRotatef(xrot, 0.0f, 1.0f, 0.0f);
		gl.glRotatef(yrot, 1.0f, 0.0f, 0.0f);
		
		gl.glNormalPointer(GL10.GL_FIXED, 0, normals);
		gl.glVertexPointer(3, GL10.GL_FIXED, 0, vertices);
		gl.glTexCoordPointer(2, GL10.GL_FIXED, 0, texCoords);

		gl.glEnableClientState(GL10.GL_NORMAL_ARRAY);
		gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
		gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
		
		
		//绘制四边形
		
		gl.glBindTexture(GL10.GL_TEXTURE_2D, texture[0]);
		gl.glDrawElements(GL10.GL_TRIANGLE_STRIP, 4,  GL10.GL_UNSIGNED_BYTE, indices1);
		gl.glBindTexture(GL10.GL_TEXTURE_2D, texture[1]);
		gl.glDrawElements(GL10.GL_TRIANGLE_STRIP, 8,  GL10.GL_UNSIGNED_BYTE, indices2);
		gl.glBindTexture(GL10.GL_TEXTURE_2D, texture[2]);
		gl.glDrawElements(GL10.GL_TRIANGLE_STRIP, 12,  GL10.GL_UNSIGNED_BYTE, indices3);
		gl.glBindTexture(GL10.GL_TEXTURE_2D, texture[3]);
		gl.glDrawElements(GL10.GL_TRIANGLE_STRIP, 16,  GL10.GL_UNSIGNED_BYTE, indices4);
		gl.glBindTexture(GL10.GL_TEXTURE_2D, texture[4]);
		gl.glDrawElements(GL10.GL_TRIANGLE_STRIP, 20,  GL10.GL_UNSIGNED_BYTE, indices5);
		gl.glBindTexture(GL10.GL_TEXTURE_2D, texture[5]);
		gl.glDrawElements(GL10.GL_TRIANGLE_STRIP, 24,  GL10.GL_UNSIGNED_BYTE, indices6);
		
	    gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
	    gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
	    gl.glDisableClientState(GL10.GL_NORMAL_ARRAY);
	    //修改旋转角度
//	    xrot+=0.3f; 
//	    yrot+=0.2f;
	    
	    //混合开关
	    if (key)
		{
	    	gl.glEnable(GL10.GL_BLEND);		// 打开混合
	    	gl.glDisable(GL10.GL_DEPTH_TEST);	// 关闭深度测试
		}
	    else 
	    {
	    	gl.glDisable(GL10.GL_BLEND);		// 关闭混合
	    	gl.glEnable(GL10.GL_DEPTH_TEST);	// 打开深度测试
		}
	}

	@Override
	public void onSurfaceChanged(GL10 gl, int width, int height)
	{
		float ratio = (float) width / height;
		//设置OpenGL场景的大小
		gl.glViewport(0, 0, width, height);
		//设置投影矩阵
		gl.glMatrixMode(GL10.GL_PROJECTION);
		//重置投影矩阵
		gl.glLoadIdentity();
		// 设置视口的大小
		gl.glFrustumf(-ratio, ratio, -1, 1, 1, 10);
		// 选择模型观察矩阵
		gl.glMatrixMode(GL10.GL_MODELVIEW);	
		// 重置模型观察矩阵
		gl.glLoadIdentity();
	}

	@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.glEnable(GL10.GL_CULL_FACE);
		// 启用阴影平滑
		gl.glShadeModel(GL10.GL_SMOOTH);
		// 启用深度测试
		gl.glEnable(GL10.GL_DEPTH_TEST);
		
		//设置光线,,1.0f为全光线,a=50%
		gl.glColor4f(1.0f,1.0f,1.0f,0.5f);	
		// 基于源象素alpha通道值的半透明混合函数
		gl.glBlendFunc(GL10.GL_SRC_ALPHA,GL10.GL_ONE);		

		//纹理相关		
		IntBuffer textureBuffer = IntBuffer.allocate(6);
		gl.glGenTextures(6, textureBuffer);
		texture = textureBuffer.array();
				
		gl.glBindTexture(GL10.GL_TEXTURE_2D, texture[0]);
		GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, GLImage.mBitmap1, 0);
		gl.glTexParameterx(GL10.GL_TEXTURE_2D,GL10.GL_TEXTURE_MAG_FILTER,GL10.GL_NEAREST); 
		gl.glTexParameterx(GL10.GL_TEXTURE_2D,GL10.GL_TEXTURE_MIN_FILTER,GL10.GL_NEAREST); 
		
		gl.glBindTexture(GL10.GL_TEXTURE_2D, texture[1]);
		GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, GLImage.mBitmap2, 0);
		gl.glTexParameterx(GL10.GL_TEXTURE_2D,GL10.GL_TEXTURE_MAG_FILTER,GL10.GL_NEAREST);
		gl.glTexParameterx(GL10.GL_TEXTURE_2D,GL10.GL_TEXTURE_MIN_FILTER,GL10.GL_NEAREST);
		
		gl.glBindTexture(GL10.GL_TEXTURE_2D, texture[2]);
		GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, GLImage.mBitmap3, 0);
		gl.glTexParameterx(GL10.GL_TEXTURE_2D,GL10.GL_TEXTURE_MAG_FILTER,GL10.GL_NEAREST); 
		gl.glTexParameterx(GL10.GL_TEXTURE_2D,GL10.GL_TEXTURE_MIN_FILTER,GL10.GL_NEAREST); 
		
		gl.glBindTexture(GL10.GL_TEXTURE_2D, texture[3]);
		GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, GLImage.mBitmap4, 0);
		gl.glTexParameterx(GL10.GL_TEXTURE_2D,GL10.GL_TEXTURE_MAG_FILTER,GL10.GL_NEAREST); 
		gl.glTexParameterx(GL10.GL_TEXTURE_2D,GL10.GL_TEXTURE_MIN_FILTER,GL10.GL_NEAREST); 
		
		gl.glBindTexture(GL10.GL_TEXTURE_2D, texture[4]);
		GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, GLImage.mBitmap5, 0);
		gl.glTexParameterx(GL10.GL_TEXTURE_2D,GL10.GL_TEXTURE_MAG_FILTER,GL10.GL_NEAREST); 
		gl.glTexParameterx(GL10.GL_TEXTURE_2D,GL10.GL_TEXTURE_MIN_FILTER,GL10.GL_NEAREST); 
		
		gl.glBindTexture(GL10.GL_TEXTURE_2D, texture[5]);
		GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, GLImage.mBitmap6, 0);
		gl.glTexParameterx(GL10.GL_TEXTURE_2D,GL10.GL_TEXTURE_MAG_FILTER,GL10.GL_NEAREST); 
		gl.glTexParameterx(GL10.GL_TEXTURE_2D,GL10.GL_TEXTURE_MIN_FILTER,GL10.GL_NEAREST); 
	
		
		//深度测试相关
		gl.glClearDepthf(1.0f);
		gl.glDepthFunc(GL10.GL_LEQUAL);
		gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_NICEST);
		gl.glEnable(GL10.GL_TEXTURE_2D);
		
		//设置环境光
	    gl.glLightfv(GL10.GL_LIGHT1, GL10.GL_AMBIENT, lightAmbient);

	    //设置漫射光
	    gl.glLightfv(GL10.GL_LIGHT1, GL10.GL_DIFFUSE, lightDiffuse);

	    //设置光源位置
	    gl.glLightfv(GL10.GL_LIGHT1, GL10.GL_POSITION, lightPosition);
	    
	    //开启一号光源
	    gl.glEnable(GL10.GL_LIGHT1);
	    
	    //开启混合
	    gl.glEnable(GL10.GL_BLEND);
	}
	
	public boolean onKeyUp(int keyCode, KeyEvent event)
	{
		key = !key;
		return false;
	}
}


最后,说说最主要的部分:onSurfaceCreated()方法中的纹理初始化。onDrawFrame()方法中绘制每个四边形的时候用不同的纹理填充。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值