绘制立方体和单个的矩阵,并映射纹理图像
绘图有很多需要注意的地方,直接提出demo,里面注释部分需要注意:
public class MainActivity extends AppCompatActivity { private GLSurfaceView glSurfaceView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); init(); } private void init() { glSurfaceView=new GLSurfaceView(this); Bitmap bitmap = BitmapFactory.decodeResource(this.getResources(), R.drawable.ayx); Bitmap bitmap2 = BitmapFactory.decodeResource(this.getResources(), R.drawable.ayx2); Bitmap mBitmap[] = {bitmap,bitmap2}; GLSurfaceView.Renderer renderer=new GLRender3(mBitmap); glSurfaceView.setRenderer(renderer); setContentView(glSurfaceView); }}package com.example.zp.myapplication; import java.nio.ByteBuffer;import java.nio.IntBuffer; import javax.microedition.khronos.egl.EGLConfig;import javax.microedition.khronos.opengles.GL10;import android.graphics.Bitmap;import android.opengl.GLUtils;import android.opengl.GLSurfaceView.Renderer; public class GLRender3 implements Renderer{ float xrot, yrot, zrot; int textureSize = 2; int texture[] = new int [textureSize]; int one = 0x10000; private Bitmap mBitmap[]; //正方体的6个面,4个点确定一个面 IntBuffer vertices = BufferUtil.intToBuffer(new int[]{ -one,-one,one, one,-one,one, one,one,one, -one,one,one, -one,-one,-one, -one,one,-one, one,one,-one, one,-one,-one, -one,one,-one, -one,one,one, one,one,one, one,one,-one, -one,-one,-one, one,-one,-one, one,-one,one, -one,-one,one, one,-one,-one, one,one,-one, one,one,one, one,-one,one, -one,-one,-one, -one,-one,one, -one,one,one, -one,one,-one, }); IntBuffer vertices2 = BufferUtil.intToBuffer(new int[]{ -one, -one, one, one, -one, one, one, one, one, -one, one, one, }); //图像的2维坐标与正方体每个面对应的坐标对应关系矩阵, //存放纹理坐标的数组,指明将绘制的第i个点(i<count)分别对应着贴图的哪一个角, // (经过实验证明纹理贴图与原来图像是上下颠倒的)四个角分别用(0,1)(左上角)、(1,1)(右上角)、(1,0)(右下角)、(0,0)(左下角)表示 IntBuffer texCoords = BufferUtil.intToBuffer(new int[]{// one,0,0,0,0,one,one,one, 0,one,one,one,one,0,0,0, 0,0,0,one,one,one,one,0, one,one,one,0,0,0,0,one, 0,one,one,one,one,0,0,0, 0,0,0,one,one,one,one,0, one,0,0,0,0,one,one,one, }); IntBuffer texCoords2= BufferUtil.intToBuffer(new int[]{ //通过实验证明生成的纹理贴图是上下颠倒的,因此vertices里一个平面对应的点应该是上下反过来,才能在矩阵上显示为正图像 //按点// 0,0,// one,0,// one,one,// 0,one //如:矩阵: 3 2 应该对应的是: 第 0个点:按点位置左下角 0 -> (0,0) 反过来去上 -> (0,1) // 0 1 ----> 第 3个点:按点位置左上角 3 -> (0,1) 反过来去下 -> (0,0) //反过来后的对应关系 0,one, one,one, one,0, 0,0 }); ByteBuffer indices = ByteBuffer.wrap(new byte[]{ 0,1,3,2, 4,5,7,6, 8,9,11,10, 12,13,15,14, 16,17,19,18, 20,21,23,22, }); public GLRender3(Bitmap mBitmap[]) { this.mBitmap = mBitmap; } @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, -4.0f); //设置3个方向的旋转 gl.glRotatef(xrot, 1.0f, 0.0f, 0.0f); gl.glRotatef(yrot, -1.0f, 0.0f, 0.0f); gl.glRotatef(zrot, 0.0f, 0.0f, 1.0f); gl.glEnableClientState(GL10.GL_VERTEX_ARRAY); gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);//启用纹理映射 //纹理和四边形对应的顶点// gl.glVertexPointer(3, GL10.GL_FIXED, 0, vertices);// gl.glTexCoordPointer(2, GL10.GL_FIXED, 0, texCoords); // //----------------绘制一个矩阵,并投影纹理---------------------------------//// // 绑定纹理// gl.glBindTexture(GL10.GL_TEXTURE_2D, texture[1]);// gl.glVertexPointer(3, GL10.GL_FIXED, 0, vertices2);// gl.glTexCoordPointer(2, GL10.GL_FIXED, 0, texCoords2);// ByteBuffer indicesi = ByteBuffer.wrap(new byte[]{//// 1,2,0,3// 0,1,3,2//// 2,3,1,0//// 3,0,2,1//// ////实验证明,第一个是逆时针画,第二个顺时针这样循环,否则不对应的就不会画// });// //4指保存的点和绘图顺序就是取连续的3个点绘制三角形。// gl.glDrawElements(GL10.GL_TRIANGLE_STRIP, 4, GL10.GL_UNSIGNED_BYTE, indicesi); // //----------------绘制一个立方体,并投影纹理---------------------------------// //下面是一下画24个点,直接投影一种纹理和 投影2中纹理 // // 投影一个纹理// gl.glVertexPointer(3, GL10.GL_FIXED, 0, vertices);// gl.glTexCoordPointer(2, GL10.GL_FIXED, 0, texCoords);// gl.glBindTexture(GL10.GL_TEXTURE_2D, texture[1]);// //用drawElments同时画24点会导致立方体内部有三角形,只是不透明看不到。
// gl.glDrawElements(GL10.GL_TRIANGLE_STRIP, 24, GL10.GL_UNSIGNED_BYTE, indices); //投影2种纹理 gl.glVertexPointer(3, GL10.GL_FIXED, 0, vertices); gl.glTexCoordPointer(2, GL10.GL_FIXED, 0, texCoords); for(int i = 0 ; i < 6 ; i++) { //当i为偶数时候投影第一个纹理,奇数时候投影第二个 if(i%2==0) gl.glBindTexture(GL10.GL_TEXTURE_2D, texture[0]); else gl.glBindTexture(GL10.GL_TEXTURE_2D, texture[1]); int first = i*4; ByteBuffer indicesi = ByteBuffer.wrap(new byte[]{ (byte) first,(byte)( first+1),(byte)( first+3),(byte)( first+2) }); gl.glDrawElements(GL10.GL_TRIANGLE_STRIP, 4, GL10.GL_UNSIGNED_BYTE, indicesi); } gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY); gl.glDisableClientState(GL10.GL_VERTEX_ARRAY); xrot+=0.5f; yrot+=0.2f; zrot+=0.3f; } @Override public void onSurfaceChanged(GL10 gl, int width, int height) { float ratio = (float) width / height; //设置OpenGL场景的大小 gl.glViewport(0, 0, width, height); //设置投影矩阵 gl.glMatrixMode(GL10.GL_PROJECTION); //重置投影矩阵 gl.glLoadIdentity(); // 设置视口的大小 gl.glFrustumf(-ratio, ratio, -1, 1, 1, 10); // 选择模型观察矩阵 gl.glMatrixMode(GL10.GL_MODELVIEW); // 重置模型观察矩阵 gl.glLoadIdentity(); } @Override public void onSurfaceCreated(GL10 gl, EGLConfig config) { // 黑色背景 gl.glClearColor(0, 0, 0, 0); //启用这条时候会只在外面粘贴纹理,而内部是黑色的
gl.glEnable(GL10.GL_CULL_FACE); // 启用阴影平滑 gl.glShadeModel(GL10.GL_SMOOTH); // 启用深度测试 gl.glEnable(GL10.GL_DEPTH_TEST); //启用纹理映射 gl.glClearDepthf(1.0f); //深度测试的类型 gl.glDepthFunc(GL10.GL_LEQUAL); //精细的透视修正 gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_NICEST); //允许2D贴图,纹理 gl.glEnable(GL10.GL_TEXTURE_2D); getTextures(gl); } private void getTextures(GL10 gl) { IntBuffer intBuffer = IntBuffer.allocate(2);//申请2个纹理存储空间 // 创建纹理 gl.glGenTextures(2 , intBuffer); //创建2个纹理,绑定intuffer texture[0] = intBuffer.get(); // 获取第一个纹理的存储指针,即纹理存储位置,位置+1 texture[1] = intBuffer.get(); //获取下一个纹理存储的位置 // 设置要使用的纹理 gl.glBindTexture(GL10.GL_TEXTURE_2D, texture[0]); //生成纹理 GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0 , mBitmap[0] , 0);//利用图mBitmap[0]生成纹理,存储在texture[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.glBindTexture(GL10.GL_TEXTURE_2D, texture[1]); GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0 , mBitmap[1] , 0);//利用图mBitmap[0]生成纹理,存储在texture[1] 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); } }立方体生成多个纹理图的效果图:

浙公网安备 33010602011771号