接着前面那一篇文章,上一篇沒有特別介紹API,這裏先介紹幾個常見的API,然後給出驗證程序:
glGenTextures(GLsizei n, GLuint *textures)
參數一:用來生成文理數量;
參數二:儲存一個紋理索引,傳入數組;
方法:根據紋理參數返回n個紋理索引;
void glBindTexture( GLenum target,
GLuint texture);
參數一: 指定紋理要綁定到的目標,可配置參數很多:GL_TEXTURE_1D, GL_TEXTURE_2D, GL_TEXTURE_3D, GL_TEXTURE_1D_ARRAY, GL_TEXTURE_2D_ARRAY, GL_TEXTURE_RECTANGLE, GL_TEXTURE_CUBE_MAP, GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_BUFFER, GL_TEXTURE_2D_MULTISAMPLE or GL_TEXTURE_2D_MULTISAMPLE_ARRAY中的一個.
一般選GL_TEXTURE_2D作爲輸入.
參數二 : 指定紋理的名稱(即ID),即第一個方法返回的紋理索引數組中的一個.
void texImage2D (int target, int level, Bitmap bitmap, int border)
參數一 : 一般設置爲GL_TEXTURE_2D;
參數二 : 一般爲0;
參數三 : 需要的圖像;
參數四 : 邊框間距(默認可以設爲0);
void glTexParameterx (int target, int pname, int param)
參數一 : 指定紋理綁定的目標,參考第二個方法參數一,一般選GL_TEXTURE_2D;
參數二 : 紋理過濾,可選GL_TEXTURE_MAG_FILTER(放大過濾)和GL_TEXTURE_MIN_FILTER(縮小過濾),當然還有GL_TEXTURE_WRAP_S,GL_TEXTURE_WRAP_T;
參數三 : 如果參數二設置爲過大過小濾鏡,這個參數一般選擇:GL_NEAREST,GL_LINEAR,其中意義:
GL_LINEAR : 使用了線性濾波(採用最靠近象素中心的四個象素的加權平均值)的紋理貼圖。這需要機器有相當高的處理能力,但GL_LINEAR提供了比較光滑的效果;
GL_NEAREST : 則採用座標最靠近象素中心的像素,這有可能使圖像走樣。從原理上講,這種方式沒有真正進行濾波。它只佔用很小的處理能力。唯一的好處是所需計算比GL_LINEAR要少,這樣我們的工程在很快和很慢的機器上都可以正常運行;
如果第二個參數不是前面兩種,一般這裏選擇GL_CLAMP,其中意義:
GL_CLAMP : 將紋理座標限制在0.0,1.0的範圍之內.如果超出了會如何呢.不會錯誤,只是會邊緣拉伸填充;
利用上面的幾個方法既可以配置所需要的紋理效果出來.
如果要綁定要圖形面上,可以在執行繪圖之前:執行綁定操作.
void glBindTexture( GLenum target,
GLuint texture);
然後再執行glDrawArrays或glDrawElements方法.
然後下面看看如何使用上面的套路來製作一個多紋理效果.
工程仍然採用上一篇的工程,只是在寫兩個類.
package org.pumpkin.pumpkinbasictexture.multexture;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.opengl.GLUtils;
import org.pumpkin.pumpkinbasictexture.R;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import javax.microedition.khronos.opengles.GL10;
/**
* Created by Administrator on 2016/5/5.
*/
public class MulTextureCube {
private int[] textures;
private Bitmap[] mBitmap=new Bitmap[6];
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 MulTextureCube(Context context){
mBitmap[0] = BitmapFactory.decodeResource(context.getResources(), R.drawable.gh);
mBitmap[1] = BitmapFactory.decodeResource(context.getResources(), R.drawable.ghh);
mBitmap[2] = BitmapFactory.decodeResource(context.getResources(), R.drawable.gtr);
mBitmap[3] = BitmapFactory.decodeResource(context.getResources(), R.drawable.ghr);
mBitmap[4] = BitmapFactory.decodeResource(context.getResources(), R.drawable.yel);
mBitmap[5] = BitmapFactory.decodeResource(context.getResources(), R.drawable.hj);
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 loadTexture(GL10 gl){
IntBuffer textBuffer=IntBuffer.allocate(6);
gl.glGenTextures(6,textBuffer);
textures=textBuffer.array();
gl.glBindTexture(GL10.GL_TEXTURE_2D,textures[0]);
GLUtils.texImage2D(GL10.GL_TEXTURE_2D,0,mBitmap[0],0);
gl.glTexParameterf(GL10.GL_TEXTURE_2D,GL10.GL_TEXTURE_MAG_FILTER,GL10.GL_NEAREST);
gl.glTexParameterf(GL10.GL_TEXTURE_2D,GL10.GL_TEXTURE_MIN_FILTER,GL10.GL_NEAREST);
gl.glBindTexture(GL10.GL_TEXTURE_2D,textures[1]);
GLUtils.texImage2D(GL10.GL_TEXTURE_2D,0,mBitmap[1],0);
gl.glTexParameterf(GL10.GL_TEXTURE_2D,GL10.GL_TEXTURE_MAG_FILTER,GL10.GL_NEAREST);
gl.glTexParameterf(GL10.GL_TEXTURE_2D,GL10.GL_TEXTURE_MIN_FILTER,GL10.GL_NEAREST);
gl.glBindTexture(GL10.GL_TEXTURE_2D,textures[2]);
GLUtils.texImage2D(GL10.GL_TEXTURE_2D,0,mBitmap[2],0);
gl.glTexParameterf(GL10.GL_TEXTURE_2D,GL10.GL_TEXTURE_MAG_FILTER,GL10.GL_NEAREST);
gl.glTexParameterf(GL10.GL_TEXTURE_2D,GL10.GL_TEXTURE_MIN_FILTER,GL10.GL_NEAREST);
gl.glBindTexture(GL10.GL_TEXTURE_2D,textures[3]);
GLUtils.texImage2D(GL10.GL_TEXTURE_2D,0,mBitmap[3],0);
gl.glTexParameterf(GL10.GL_TEXTURE_2D,GL10.GL_TEXTURE_MAG_FILTER,GL10.GL_NEAREST);
gl.glTexParameterf(GL10.GL_TEXTURE_2D,GL10.GL_TEXTURE_MIN_FILTER,GL10.GL_NEAREST);
gl.glBindTexture(GL10.GL_TEXTURE_2D,textures[4]);
GLUtils.texImage2D(GL10.GL_TEXTURE_2D,0,mBitmap[4],0);
gl.glTexParameterf(GL10.GL_TEXTURE_2D,GL10.GL_TEXTURE_MAG_FILTER,GL10.GL_NEAREST);
gl.glTexParameterf(GL10.GL_TEXTURE_2D,GL10.GL_TEXTURE_MIN_FILTER,GL10.GL_NEAREST);
gl.glBindTexture(GL10.GL_TEXTURE_2D,textures[5]);
GLUtils.texImage2D(GL10.GL_TEXTURE_2D,0,mBitmap[5],0);
gl.glTexParameterf(GL10.GL_TEXTURE_2D,GL10.GL_TEXTURE_MAG_FILTER,GL10.GL_NEAREST);
gl.glTexParameterf(GL10.GL_TEXTURE_2D,GL10.GL_TEXTURE_MIN_FILTER,GL10.GL_NEAREST);
}
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.glBindTexture(GL10.GL_TEXTURE_2D,textures[0]);
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.glBindTexture(GL10.GL_TEXTURE_2D,textures[1]);
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.glBindTexture(GL10.GL_TEXTURE_2D,textures[2]);
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.glBindTexture(GL10.GL_TEXTURE_2D,textures[3]);
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.glBindTexture(GL10.GL_TEXTURE_2D,textures[4]);
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.glBindTexture(GL10.GL_TEXTURE_2D,textures[5]);
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);
}
}
記得在工程drawable下添加6張不同的圖片.
渲染器類如下:
package org.pumpkin.pumpkinbasictexture.multexture;
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/5.
*/
public class PumpKinTextureRender implements GLSurfaceView.Renderer {
private MulTextureCube mulTextureCube;
private float angleTex=0;
private float speechTex=-1.5f;
public PumpKinTextureRender(Context context){
mulTextureCube=new MulTextureCube(context);
}
@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);
mulTextureCube.loadTexture(gl);
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,-8.0f);
gl.glRotatef(angleTex,0.1f,1.0f,0.2f);
mulTextureCube.draw(gl);
angleTex+=speechTex;
}
}
運行效果: