Android之GLSurfaceView立方体各面不同图片纹理测试代码2

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/chenyefei/article/details/51614376

创建4个顶点构成的一个面,不同的面依次先对该面纹理贴图,然后根据贴图的面进行变换来得到不同的面,最后就可组装成一个立方体了。 之前的《Android之GLSurfaceView立方体各面不同图片纹理测试代码》则为一次性创建上所有的顶点,然后分别对各自的面进行纹理贴图显示的立方体。

public class MainActivity extends Activity {

	private GLSurfaceView mGLView; 
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
	
		mGLView = new DemoGLSurfaceView(this);
        setContentView(mGLView); 
	}
}
class DemoGLSurfaceView extends GLSurfaceView{  
	DomeGLRender mRenderer;  
    public DemoGLSurfaceView(Context context) {  
        super(context);  
        mRenderer = new DomeGLRender(context.getResources());  
        this.setRenderer(mRenderer);  
    }  
      
    public boolean onTouchEvent(final MotionEvent event){  
        this.queueEvent(new Runnable() {   
            @Override  
            public void run() {  
            	if(mRenderer.bLight){
            		mRenderer.bLight = false;
            	}else{
            		mRenderer.bLight = true;
            	}
            }  
        });  
        return true;  
    }   
} 

class DomeGLRender implements Renderer  {  
   
    public boolean bLight = true;//是否开启灯光  
    private float[] vertices = { // 定义一个面的顶点坐标
    		-1.0f, -1.0f, 0.0f,  // 0. 左-底-前
    		1.0f, -1.0f, 0.0f,   // 1. 右-底-前
    		-1.0f,  1.0f, 0.0f,  // 2. 左-顶-前
    		1.0f,  1.0f, 0.0f    // 3. 右-顶-前 
    }; 
    private float[] textCood = { 
            0.0f, 1.0f,  // A. 左-下
            1.0f, 1.0f,  // B. 右-下 
            0.0f, 0.0f,  // C. 左-上 
            1.0f, 0.0f   // D. 右-上
    };  
      
    float xrot,yrot; //旋转  
    private int[] textures = new int[1];  
    private FloatBuffer vertexBuffer; //顶点缓冲  
    private FloatBuffer textCoodBuffer; //纹理缓冲  

    //环境光  
    private float[] lightAmbient = {0.5f,0.5f,0.5f,1.0f};  
    private FloatBuffer AmbientBuffer;  
    //漫射光  
    private float[] lightDiffuse = {1.0f,1.0f,1.0f,1.0f}; 
    private FloatBuffer diffuseBuffer;  
    //光源位置  
    private float[] lightPosition = {0.0f,0.0f,2.0f,1.0f};
    private FloatBuffer positionBuffer;  
    //图片数组
    public static Bitmap[] mBitmap = new Bitmap[6]; 
    //变换角度
    private float[] angle = {0.0f, 90.0f, 180.0f, 270.0f, 90.0f, 270.0f};
    //构造函数
    public DomeGLRender(Resources resources){
    	mBitmap[0] = BitmapFactory.decodeResource(resources, R.drawable.img0);
    	mBitmap[1] = BitmapFactory.decodeResource(resources, R.drawable.img1);  
    	mBitmap[2] = BitmapFactory.decodeResource(resources, R.drawable.img2);  
    	mBitmap[3] = BitmapFactory.decodeResource(resources, R.drawable.img0);  
    	mBitmap[4] = BitmapFactory.decodeResource(resources, R.drawable.img1);  
    	mBitmap[5] = BitmapFactory.decodeResource(resources, R.drawable.img2);  
    	 
        //顶点  
        ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length * 4);  
        vbb.order(ByteOrder.nativeOrder());  
        vertexBuffer = vbb.asFloatBuffer();  
        vertexBuffer.put(vertices);  
        vertexBuffer.position(0);  
          
        //纹理  
        ByteBuffer tbb = ByteBuffer.allocateDirect(textCood.length * 4);  
        tbb.order(ByteOrder.nativeOrder());  
        textCoodBuffer = tbb.asFloatBuffer();               
        textCoodBuffer.put(textCood);    
        textCoodBuffer.position(0);  
          
        //环境光  
        ByteBuffer ambientbb = ByteBuffer.allocateDirect(lightAmbient.length * 4);  
        ambientbb.order(ByteOrder.nativeOrder());  
        AmbientBuffer = ambientbb.asFloatBuffer();  
        AmbientBuffer.put(lightAmbient);  
        AmbientBuffer.position(0);  
          
        //漫射光  
        ByteBuffer diffusebb = ByteBuffer.allocateDirect(lightDiffuse.length * 4);  
        diffusebb.order(ByteOrder.nativeOrder());  
        diffuseBuffer = diffusebb.asFloatBuffer();  
        diffuseBuffer.put(lightDiffuse);  
        diffuseBuffer.position(0);  
          
        //灯光位置  
        ByteBuffer positionbb = ByteBuffer.allocateDirect(lightPosition.length * 4);  
        positionbb.order(ByteOrder.nativeOrder());  
        positionBuffer = positionbb.asFloatBuffer();  
        positionBuffer.put(lightPosition);  
        positionBuffer.position(0);  
          
    }  
      
    @Override  
    public void onDrawFrame(GL10 gl) {  
        //清除颜色和深度缓存  
        gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);  
        gl.glLoadIdentity();  
          
        //启用灯光  
        gl.glEnable(GL10.GL_LIGHTING);  
          
        //启用顶点和纹理缓存  
        gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);  
        gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);  
        //移动和旋转设置  
        gl.glTranslatef(0.0f, 0.0f, -6.0f);  
        gl.glRotatef(xrot, 1.0f, 0.0f, 0.0f);  
        gl.glRotatef(yrot, 0.0f, 1.0f, 0.0f); 
        
        gl.glFrontFace(GL10.GL_CCW);    // 正前面为逆时针方向
	    gl.glEnable(GL10.GL_CULL_FACE); // 使能剔除面
	    gl.glCullFace(GL10.GL_BACK);    // 剔除背面(不显示)
	    
	    gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
	    gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer);
	    gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);  // 使能纹理坐标数组
	    gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, textCoodBuffer); // 定义纹理坐标数组缓冲区
          
        //绘制六个面,贴图  
        for (int i = 0; i < 6; i++) {  
        	GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, mBitmap[i], 0); 
        	gl.glPushMatrix();
		    if(i < 4)
		    	gl.glRotatef(angle[i], 0.0f, 1.0f, 0.0f);//y轴为中心变换
		    else
		    	gl.glRotatef(angle[i], 1.0f, 0.0f, 0.0f);//x轴为中心变换
		    gl.glTranslatef(0.0f, 0.0f, 1.0f);                                
            gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4);  
            gl.glPopMatrix();
        }  
        
        // 恢复原来的状态
	    gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY); 
	    gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
	    gl.glDisable(GL10.GL_CULL_FACE); 
           
        xrot += 0.5f;  
        yrot += 0.5f;  
         
        if (!bLight) {  
            gl.glDisable(GL10.GL_LIGHT1);  
        } else {  
            gl.glEnable(GL10.GL_LIGHT1);  
        }  
    }  
  
    @Override  
    public void onSurfaceChanged(GL10 gl, int width, int height) {  
        //场景大小  
        gl.glViewport(0, 0, width, height);  
        float ratio = (float) width / height;  
        //投影矩阵  
        gl.glMatrixMode(GL10.GL_PROJECTION);  
        //重置下  
        gl.glLoadIdentity();  
        
		// 设置视图区域的大小
		GLU.gluPerspective(gl, 45.0f, (float)width/(float)height,0.1f,100.0f);
		// 选择模型观察矩阵
		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, 0, 0, 0);  
        //启用阴影平滑  
        gl.glShadeModel(GL10.GL_SMOOTH);  
        //清除深度缓存  
        gl.glClearDepthf(1f);  
        //启用深度缓存  
        gl.glEnable(GL10.GL_DEPTH_TEST);  
        //深度缓存模式  
        gl.glDepthFunc(GL10.GL_LEQUAL);  
           
        //启用纹理  
        gl.glEnable(GL10.GL_TEXTURE_2D);  
        //创建纹理  
        gl.glGenTextures(1, textures, 0);  
        //绑定纹理  
        gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]);  
        //生成纹理  
        GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, mBitmap[0], 0);  
        //线性滤波处理  
        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);  
          
        //设置环境光  
        gl.glLightfv(GL10.GL_LIGHT1, GL10.GL_AMBIENT, AmbientBuffer);  
        //设置漫射光  
        gl.glLightfv(GL10.GL_LIGHT1, GL10.GL_DIFFUSE, diffuseBuffer);  
        //设置灯光位置  
        gl.glLightfv(GL10.GL_LIGHT1, GL10.GL_POSITION, positionBuffer);  
        //启用1号灯光  
        gl.glEnable(GL10.GL_LIGHT1);          
    }  
} 
源码下载: 点击打开链接

猜你喜欢

转载自blog.csdn.net/chenyefei/article/details/51614376