Android OpenGL10 紋理

前面一篇中簡述了基本圖形的繪製,並且給出着色,下面看看如何在一個立方體上面覆蓋一層紋理,就像在地板上貼了一層地板磚的效果.

同樣新建一個android studio工程,PumpKinBasicTexture工程:

主類如下:

package org.pumpkin.pumpkinbasictexture;

import android.app.Activity;
import android.app.ActionBar;
import android.app.Fragment;
import android.opengl.GLSurfaceView;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.os.Build;

import org.pumpkin.pumpkinbasictexture.texture.DurianTextureRender;


public class PumpKinMainActivity extends Activity {

    private GLSurfaceView glSurfaceView;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        glSurfaceView=new GLSurfaceView(this);
        glSurfaceView.setRenderer(new DurianTextureRender(this));
        setContentView(glSurfaceView);

    }

}


繪製紋理類如下:

package org.pumpkin.pumpkinbasictexture.texture;

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

import org.pumpkin.pumpkinbasictexture.R;

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

import javax.microedition.khronos.opengles.GL10;

/**
 * Created by Administrator on 2016/5/4.
 */
public class TextureCube {

    private FloatBuffer vertexBuffer;
    private FloatBuffer texBuffer;

    private float[] vertices={
            -1.0f, -1.0f, 0.0f,  // 0. left-bottom-front
            1.0f, -1.0f, 0.0f,  // 1. right-bottom-front
            -1.0f,  1.0f, 0.0f,  // 2. left-top-front
            1.0f,  1.0f, 0.0f   // 3. right-top-front
    };

    float[] texCoords={
            0.0f, 1.0f,  // A. left-bottom (NEW)
            1.0f, 1.0f,  // B. right-bottom (NEW)
            0.0f, 0.0f,  // C. left-top (NEW)
            1.0f, 0.0f   // D. right-top (NEW)
    };

    int[] textureIDs=new int[1];

    public TextureCube(){
        ByteBuffer vbb=ByteBuffer.allocateDirect(vertices.length*4);
        vbb.order(ByteOrder.nativeOrder());

        vertexBuffer=vbb.asFloatBuffer();
        vertexBuffer.put(vertices);
        vertexBuffer.position(0);

        ByteBuffer tbb=ByteBuffer.allocateDirect(texCoords.length*4);
        tbb.order(ByteOrder.nativeOrder());
        texBuffer=tbb.asFloatBuffer();
        texBuffer.put(texCoords);
        texBuffer.position(0);

    }

    public void draw(GL10 gl){

        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,texBuffer);

        //front
        gl.glPushMatrix();
        gl.glTranslatef(0.0f,0.0f,1.0f);
        gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP,0,4);
        gl.glPopMatrix();

        //left
        gl.glPushMatrix();
        gl.glRotatef(270.0f,0.0f,1.0f,0.0f);
        gl.glTranslatef(0.0f,0.0f,1.0f);
        gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP,0,4);
        gl.glPopMatrix();

        //back
        gl.glPushMatrix();
        gl.glRotatef(180.0f, 0.0f, 1.0f, 0.0f);
        gl.glTranslatef(0.0f, 0.0f, 1.0f);
        gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4);
        gl.glPopMatrix();

        // right
        gl.glPushMatrix();
        gl.glRotatef(90.0f, 0.0f, 1.0f, 0.0f);
        gl.glTranslatef(0.0f, 0.0f, 1.0f);
        gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4);
        gl.glPopMatrix();

        // top
        gl.glPushMatrix();
        gl.glRotatef(270.0f, 1.0f, 0.0f, 0.0f);
        gl.glTranslatef(0.0f, 0.0f, 1.0f);
        gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4);
        gl.glPopMatrix();

        // bottom
        gl.glPushMatrix();
        gl.glRotatef(90.0f, 1.0f, 0.0f, 0.0f);
        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);

    }

    public void loadTexture(GL10 gl,Context context){

        gl.glGenTextures(1,textureIDs,0);
        gl.glBindTexture(GL10.GL_TEXTURE_2D,textureIDs[0]);
        gl.glTexParameterf(GL10.GL_TEXTURE_2D,GL10.GL_TEXTURE_MIN_FILTER,GL10.GL_NEAREST);
        gl.glTexParameterf(GL10.GL_TEXTURE_2D,GL10.GL_TEXTURE_MIN_FILTER,GL10.GL_LINEAR);

        InputStream istream=context.getResources().openRawResource(R.drawable.ghh);
        Bitmap bitmap;

        bitmap= BitmapFactory.decodeStream(istream);

        try {
            istream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

        GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0);
        bitmap.recycle();

    }

}

其中:

gl.glPushMatrix();
gl.glPopMatrix();

glPushMatrix()和glPopMatrix()的配對使用可以消除上一次的變換對本次變換的影響。使本次變換是以世界座標系的原點爲參考點進行.有點類似畫地爲牢的概念,即在繪製圖形的時候,在設定某一個座標系中繪製後,然後座標變換,並不會影響前面,那個繪製的圖形還在以前的位置,不會因爲座標變換了,圖形位置發生了變化.

gl.glGenTextures(1,textureIDs,0);

生成一個紋理對象,並將其ID保存到成員變量 texture 中.

gl.glBindTexture(GL10.GL_TEXTURE_2D,textureIDs[0]);

將生成的空紋理綁定到當前2D紋理通道

gl.glTexParameterf(GL10.GL_TEXTURE_2D,GL10.GL_TEXTURE_MIN_FILTER,GL10.GL_NEAREST);
        gl.glTexParameterf(GL10.GL_TEXTURE_2D,GL10.GL_TEXTURE_MIN_FILTER,GL10.GL_LINEAR);

設置2D紋理通道當前綁定的紋理的屬性

GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0);

將bitmap應用到2D紋理通道當前綁定的紋理中

下面是渲染器:

package org.pumpkin.pumpkinbasictexture.texture;

import android.content.Context;
import android.opengl.GLSurfaceView;
import android.opengl.GLU;

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

/**
 * Created by Administrator on 2016/5/4.
 */
public class DurianTextureRender implements GLSurfaceView.Renderer {

    private Context mContext;

    private TextureCube textureCube;
    private float angleTex=0;
    private float speechTex=-1.5f;



    public DurianTextureRender(Context context){
        mContext=context;

        textureCube=new TextureCube();

    }
    @Override
    public void onSurfaceCreated(GL10 gl, EGLConfig config) {

        gl.glClearColor(0.0f,0.0f,0.0f,1.0f);
        gl.glClearDepthf(1.0f);
        gl.glEnable(GL10.GL_DEPTH_TEST);
        gl.glDepthFunc(GL10.GL_LEQUAL);
        gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT,GL10.GL_NICEST);
        gl.glShadeModel(GL10.GL_SMOOTH);
        gl.glDisable(GL10.GL_DITHER);

        textureCube.loadTexture(gl,mContext);
        gl.glEnable(GL10.GL_TEXTURE_2D);

    }

    @Override
    public void onSurfaceChanged(GL10 gl, int width, int height) {

        if(height==0){
            height=1;
        }
        float aspect=(float)width/height;

        gl.glViewport(0,0,width,height);

        gl.glMatrixMode(GL10.GL_PROJECTION);
        gl.glLoadIdentity();
        GLU.gluPerspective(gl, 45, aspect, 0.1f, 100.0f);

        gl.glMatrixMode(GL10.GL_MODELVIEW);
        gl.glLoadIdentity();

    }

    @Override
    public void onDrawFrame(GL10 gl) {

        gl.glClear(GL10.GL_COLOR_BUFFER_BIT|GL10.GL_DEPTH_BUFFER_BIT);

        gl.glLoadIdentity();
        gl.glTranslatef(0.0f,0.0f,-6.0f);
        gl.glRotatef(angleTex,0.1f,1.0f,0.2f);
        textureCube.draw(gl);

        angleTex+=speechTex;

    }

}


添加紋理需要使能:

gl.glEnable(GL10.GL_TEXTURE_2D);

運行結果如下:












發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章