Android OpenGL ES 應用(二) 紋理

來源:互聯網
上載者:User

Android OpenGL ES 應用(二) 紋理

 

要是做複雜的OpenGL應用程式,一定會用到紋理技術。紋理說白了就是把圖片或者視頻映像繪製到OpenGL空間中。

因此紋理也有座標系,稱ST座標,或者UV

 

 

上面是紋理座標空間,但沒有固定的方向

下面示範載入一張image作為紋理貼圖。

 

 

public class TextureUtils {public static int createTexture(InputStream ins) {int[] textures = new int[1];GLES20.glGenTextures(1, textures, 0);//產生一個紋理int textureId = textures[0];GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureId);GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER,GLES20.GL_NEAREST); GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D,GLES20.GL_TEXTURE_MAG_FILTER,GLES20.GL_LINEAR);GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S,GLES20.GL_CLAMP_TO_EDGE);GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T,GLES20.GL_CLAMP_TO_EDGE);//上面是紋理貼圖的取樣方式,包括展開方式,取臨近值和線性值Bitmap bitmap = BitmapFactory.decodeStream(ins);GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bitmap, 0);//讓圖片和紋理關聯起來,載入到OpenGl空間中Log.d(OPENGL,bitmap: + bitmap);bitmap.recycle();//不需要,可以釋放return textureId;}}

 

 

 

 

public class MyRenderer implements Renderer {public static float[] projMatrix = new float[16];// 投影public static float[] viewMatrix = new float[16];// 相機public static float[] mViewPjMatrix;// 總變換矩陣public static float[] matrixs = new float[16];public static int textureId = -1;Context context;MyDrawModel drawModel;public MyRenderer(Context context) {this.context = context;}@Overridepublic void onDrawFrame(GL10 arg0) {GLES20.glClear( GLES20.GL_DEPTH_BUFFER_BIT | GLES20.GL_COLOR_BUFFER_BIT);Log.e(, textureId: + textureId);drawModel.drawFrame(textureId);}@Overridepublic void onSurfaceChanged(GL10 arg0, int w, int h) {GLES20.glViewport(0, 0, w, h);float ratio = (float) w / h;Matrix.frustumM(projMatrix, 0, -ratio, ratio, -1, 1, 1, 10);//投影矩陣設定Matrix.setLookAtM(viewMatrix, 0, 0, 0, 3, 0, 0, 0, 0.0f, 1.0f, 0.0f);//攝像機座標設定}@Overridepublic void onSurfaceCreated(GL10 g, EGLConfig eglConfig) {GLES20.glClearColor(0.5f,0.5f,0.5f, 1.0f);  GLES20.glEnable(GLES20.GL_DEPTH_TEST);InputStream ins = null;drawModel = new MyDrawModel();drawModel.init();try {ins = context.getAssets().open(house.jpg);textureId = TextureUtils.createTexture(ins);Log.e(, textureId: + textureId);} catch (IOException e) {e.printStackTrace();} finally {try {ins.close();} catch (IOException e) {e.printStackTrace();}}GLES20.glDisable(GLES20.GL_CULL_FACE);}}


 

public class MyDrawModel {private int programId;private int mVPMatrixHandle; // 總變換矩陣引用idprivate int positionHandle; // 頂點位置idprivate int texCoorHandle; // 頂點紋理座標idprivate FloatBuffer vertexBuffer;private FloatBuffer texCoorBuffer;public MyDrawModel() {}public void init() {initData();int vertexsharder = GLHelper.compileScript(GLES20.GL_VERTEX_SHADER,GLScript.vertex2);int fragmentsharder = GLHelper.compileScript(GLES20.GL_FRAGMENT_SHADER,GLScript.fragment2);programId = GLHelper.linkAttach(vertexsharder, fragmentsharder);boolean isOK = GLHelper.checkProgram(programId);positionHandle = GLES20.glGetAttribLocation(programId, aPosition);texCoorHandle = GLES20.glGetAttribLocation(programId, aTexCoor);mVPMatrixHandle = GLES20.glGetUniformLocation(programId, uMVPMatrix);Log.d(OPENGL, positionHandle: + positionHandle + ;texCoorHandle:+ texCoorHandle + ;mVPMatrixHandle: + mVPMatrixHandle + ;+ isOK);}private void initData() {//X,Y,Z,繪畫的頂點float vertices[] = new float[] {           0,     0, 0,   -1.8f, -1f, 0,   1.8f, -1f, 0,   1.8f,  1f, 0,   -1.8f,  1f, 0,   -1.8f, -1f, 0   };ByteBuffer vb = ByteBuffer.allocateDirect(vertices.length * 4);vb.order(ByteOrder.nativeOrder());vertexBuffer = vb.asFloatBuffer();vertexBuffer.put(vertices);vertexBuffer.position(0);//紋理空間座標 S,Tfloat texCoor[] = new float[] { 0.5f, 0.5f,0f,     1f,1f,     1f,1f,     0f,0f,     0f,0f,     1f };ByteBuffer cb = ByteBuffer.allocateDirect(texCoor.length * 4);cb.order(ByteOrder.nativeOrder());texCoorBuffer = cb.asFloatBuffer();texCoorBuffer.put(texCoor);texCoorBuffer.position(0);}public void drawFrame(int textureId) { GLES20.glUseProgram(programId);  // // 初始化矩陣 Matrix.setRotateM(MyRenderer.matrixs, 0, 0, 1, 0, 0); Matrix.translateM(MyRenderer.matrixs, 0, 0, 0, 1);  //矩陣轉換 ,投影矩陣,攝像機矩陣,模型矩陣 MyRenderer.mViewPjMatrix = new float[16]; Matrix.multiplyMM(MyRenderer.mViewPjMatrix, 0, MyRenderer.viewMatrix,0, MyRenderer.matrixs, 0); Matrix.multiplyMM(MyRenderer.mViewPjMatrix, 0, MyRenderer.projMatrix,0, MyRenderer.mViewPjMatrix, 0); GLES20.glUniformMatrix4fv(mVPMatrixHandle, 1, false, MyRenderer.mViewPjMatrix, 0); GLES20.glVertexAttribPointer(positionHandle, 3, GLES20.GL_FLOAT, false, 3 * 4, vertexBuffer); GLES20.glVertexAttribPointer(texCoorHandle,  2, GLES20.GL_FLOAT, false, 2 * 4, texCoorBuffer); GLES20.glEnableVertexAttribArray(positionHandle); GLES20.glEnableVertexAttribArray(texCoorHandle); GLES20.glActiveTexture(GLES20.GL_TEXTURE0); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureId); GLES20.glDrawArrays(GLES20.GL_TRIANGLE_FAN, 0, 6);//六個定點,繪製三角形}}


OpenGL需要把裝置的座標歸一化到[-1,-1]空間中,所以這裡涉及到矩陣相乘的理論,包括全局座標,物體座標,攝像機座標的轉換,以後會詳細介紹。


 

public class GLScript {public GLScript() {}public static final String vertex1 = attribute vec4 mPosition; +              void main() +              { +                  gl_Position=mPosition;  +              };        public static final String fragment1 = precision mediump float; +              uniform vec4 mColor; +              void main(){ gl_FragColor=mColor;};          public static final String vertex2 = uniform mat4 uMVPMatrix;     + attribute vec3 aPosition;     + attribute vec2 aTexCoor;     + varying vec2 vTextureCoord;      + void main() {      + gl_Position = uMVPMatrix * vec4(aPosition,1);     + vTextureCoord = aTexCoor;      + }    ;        public static final String fragment2 = precision mediump float;    + varying vec2 vTextureCoord;    + uniform sampler2D sTexture;    + void main() {     + vec2 coord =  vTextureCoord;    + coord.s =  coord.s * 0.5; //其實是去映像的一半,向量縮小了    + gl_FragColor = texture2D(sTexture, coord);     + }    ;}


 

 

coord.s =  coord.s * 0.5;
這樣是取紋理映像的一半,顯示到介面上也就是圖片的前半部分內容

 

 

其它的工具類和上一篇文章一樣。

 

內容顯示

 

 

原圖:

 

 

 

 

 

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.