【Android开发学习15】Android OpenGL ES 纹理映射之glDrawArrays

目标: 为四方体的每个面贴上一张图片,并自动旋转。

 

一、基础知识:


1.初始化:

 // 1.允许2D贴图,纹理
 gl.glEnable(GL10.GL_TEXTURE_2D);
 // 2.创建纹理
 gl.glGenTextures(1, textureids, 0);
 // 3.绑定要使用的纹理
 gl.glBindTexture(GL10.GL_TEXTURE_2D, textureids[0]);
 // 4.生成纹理
 GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, GLImage.iBitmap, 0); 
 // 5.线性滤波
 gl.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER,GL10.GL_LINEAR);
 gl.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER,GL10.GL_LINEAR);

2.使用:

 // 1.清除屏幕和深度缓存
 gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
 // 2.重置当前的模型观察矩阵
 gl.glLoadIdentity(); 
 // 3.开启顶点和纹理功能(开启顶点和纹理缓冲)
 gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
 gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY); 
 // 4.设置点点和纹理
 gl.glVertexPointer(3, GL10.GL_FIXED, 0, vertexBuffer);
 gl.glTexCoordPointer(2, GL10.GL_FIXED, 0, texBuffer);
 // 5.向z轴里移入6.0f
 gl.glTranslatef(0.0f, 0.0f, -5.0f);
 // 6.设置3个方向的旋转
 gl.glRotatef(xrot, 1.0f, 0.0f, 0.0f);
 gl.glRotatef(yrot, 0.0f, 1.0f, 0.0f);
 gl.glRotatef(zrot, 0.0f, 0.0f, 1.0f);
 // 7.绘制正方体
 for (int i = 0; i < 6; i++) {
  switch(i)
  {
         case 0:
             // 8.生成纹理
             GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, GLImage.iBitmap, 0);
             break;
         }          
            gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, i * 4, 4);
 }

 // 9.关闭顶点和纹理功能
 gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
 gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
    
 // 10.调节旋转角度
 xrot+=0.5f;
 yrot+=0.4f;
 zrot+=0.6f;

 

3.补充说明,相对上一节中,我多添加了一个函数:

public GLRender(Context context) {
        this.context = context;
        // 初始化
        textureids = new int[1];

        ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length * 4);
        vbb.order(ByteOrder.nativeOrder());
        vertexBuffer = vbb.asIntBuffer();
        vertexBuffer.put(vertices);
        vertexBuffer.position(0);

        ByteBuffer tbb = ByteBuffer.allocateDirect(texCoords.length * 4 * 6);
        tbb.order(ByteOrder.nativeOrder());
        texBuffer = tbb.asIntBuffer();
        //为每一个面贴上纹理
        for (int i = 0; i < 6; i++) {
            texBuffer.put(texCoords);
        }
        texBuffer.position(0);
    }

主要是对各个面的顶点做一个初始化。

 

 

 

二、实现:

1. 界面编辑:
res\layout\main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
<TextView  
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:text="@string/hello"
    />

<Button
    android:id="@+id/button1"
    android:layout_width="145dp"
    android:layout_height="wrap_content"
    android:text="演示开始" />

</LinearLayout>


2.代码编辑:
\src\com\yarin\android\Examples\Activity01.java

package com.yarin.android.Examples_12_05;

import java.io.IOException;
import java.io.InputStream;

import javax.microedition.khronos.opengles.GL10;

import android.app.Activity;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.opengl.GLSurfaceView;
import android.opengl.GLUtils;
import android.opengl.GLSurfaceView.Renderer;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;

public class Activity01 extends Activity
{
	Renderer render = new GLRender(this);
	GLSurfaceView glView;
	Button start;			// 演示开始

	
	/** Called when the activity is first created. */
	@Override
	public void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);
		GLImage.load(this.getResources());
		glView = new GLSurfaceView(this);
		
		
		glView.setRenderer(render);
		setContentView(R.layout.main);
		start=(Button)findViewById(R.id.button1);	// "演示开始"按钮初始化
		start.setOnClickListener(new View.OnClickListener() {
			
			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
				setContentView(glView);
			}
		});
		

		//setContentView(glView);
	}
}


class GLImage
{
	public static Bitmap iBitmap;
	public static Bitmap jBitmap;
	public static Bitmap kBitmap;
	public static Bitmap lBitmap;
	public static Bitmap mBitmap;
	public static Bitmap nBitmap;
	public static Bitmap close_Bitmap;
	
	
	public static void load(Resources resources)
	{
		iBitmap = BitmapFactory.decodeResource(resources, R.drawable.img);
		jBitmap = BitmapFactory.decodeResource(resources, R.drawable.jmg);
		kBitmap = BitmapFactory.decodeResource(resources, R.drawable.kmg);
		lBitmap = BitmapFactory.decodeResource(resources, R.drawable.lmg);
		mBitmap = BitmapFactory.decodeResource(resources, R.drawable.mmg);
		nBitmap = BitmapFactory.decodeResource(resources, R.drawable.nmg);
		close_Bitmap = BitmapFactory.decodeResource(resources, R.drawable.close);
	}
}


 

\src\com\yarin\android\Examples\GLRender.java

package com.yarin.android.Examples_12_05;

import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;
import java.nio.IntBuffer;
import java.nio.ByteOrder;  

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

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.opengl.GLUtils;
import android.opengl.GLSurfaceView.Renderer;
import android.content.Context;

public class GLRender implements Renderer
{
	public Context context;
    private int[] textureids;
    private IntBuffer vertexBuffer;
    private IntBuffer texBuffer;
    private	float xrot, yrot, zrot;
    private	int one = 0x10000;
	
	// 正方体顶点
    private int[] vertices = {
            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
        };

    //纹理点
    private int[] texCoords = {  
            0, one,                
            one, one,
            0, 0,
            one, 0
    };

    public GLRender(Context context) {
        this.context = context;
        // 初始化
        textureids = new int[1];

        ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length * 4);
        vbb.order(ByteOrder.nativeOrder());
        vertexBuffer = vbb.asIntBuffer();
        vertexBuffer.put(vertices);
        vertexBuffer.position(0);

        ByteBuffer tbb = ByteBuffer.allocateDirect(texCoords.length * 4 * 6);
        tbb.order(ByteOrder.nativeOrder());
        texBuffer = tbb.asIntBuffer();
        //为每一个面贴上纹理
        for (int i = 0; i < 6; i++) {
            texBuffer.put(texCoords);
        }
        texBuffer.position(0);
    }

	@Override
	public void onDrawFrame(GL10 gl)
	{
		// 1.清除屏幕和深度缓存
		gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);

		// 2.重置当前的模型观察矩阵
		gl.glLoadIdentity();
		
		// 3.开启顶点和纹理功能(开启顶点和纹理缓冲)
		gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
		gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
		
	     // 4.设置点点和纹理
        gl.glVertexPointer(3, GL10.GL_FIXED, 0, vertexBuffer);
        gl.glTexCoordPointer(2, GL10.GL_FIXED, 0, texBuffer); 

        // 5.向z轴里移入6.0f
        gl.glTranslatef(0.0f, 0.0f, -5.0f);

        // 6.设置3个方向的旋转
        gl.glRotatef(xrot, 1.0f, 0.0f, 0.0f);
        gl.glRotatef(yrot, 0.0f, 1.0f, 0.0f);
        gl.glRotatef(zrot, 0.0f, 0.0f, 1.0f);

        // 7.绘制正方体
        for (int i = 0; i < 6; i++) {
        	switch(i)
        	{
        	case 0:
    	        // 8.生成纹理
    	        GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, GLImage.iBitmap, 0);
    	        break;
        	case 1:
    	        // 生成纹理
    	        GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, GLImage.jBitmap, 0);
    	        break;
        	case 2:
    	        // 生成纹理
    	        GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, GLImage.kBitmap, 0);
    	        break;
        	case 3:
    	        // 生成纹理
    	        GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, GLImage.lBitmap, 0);
    	        break;
        	case 4:
    	        // 生成纹理
    	        GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, GLImage.mBitmap, 0);
    	        break;
        	case 5:
    	        // 生成纹理
    	        GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, GLImage.nBitmap, 0);
    	        break;    	                		
        	}
        		
            gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, i * 4, 4);
        }

        // 9.关闭顶点和纹理功能
	    gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
	    gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
	    
	    // 10.调节旋转角度
	    xrot+=0.5f;
	    yrot+=0.4f; 
	    zrot+=0.6f; 
		
	}

	@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.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_FASTEST);  

		// 绿色背景
		gl.glClearColor(0, 1, 0, 0);
		
		gl.glEnable(GL10.GL_CULL_FACE);
		// 启用阴影平滑
		gl.glShadeModel(GL10.GL_SMOOTH);
		// 启用深度测试
		gl.glEnable(GL10.GL_DEPTH_TEST);
		
		//启用纹理映射
		gl.glClearDepthf(1.0f);
		//深度测试的类型
		gl.glDepthFunc(GL10.GL_LEQUAL);
	
	
		// 1.允许2D贴图,纹理
		gl.glEnable(GL10.GL_TEXTURE_2D);
		// 2.创建纹理
		gl.glGenTextures(1, textureids, 0);
		// 3.绑定要使用的纹理
		gl.glBindTexture(GL10.GL_TEXTURE_2D, textureids[0]);
		// 4.生成纹理
		GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, GLImage.iBitmap, 0);
		
		// 5.线性滤波
		gl.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER,GL10.GL_LINEAR);
		gl.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER,GL10.GL_LINEAR);
			
	}

}


 

 

三、效果:

 

 

 

 

 本文博客源地址:http://blog.csdn.net/ypist

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值