接着前面那一篇文章,上一篇没有特别介绍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; } }
运行效果: