Android之GLSurfaceView立方体各面不同图片纹理测试代码2
2016-06-08 17:10
369 查看
创建4个顶点构成的一个面,不同的面依次先对该面纹理贴图,然后根据贴图的面进行变换来得到不同的面,最后就可组装成一个立方体了。 之前的《Android之GLSurfaceView立方体各面不同图片纹理测试代码》则为一次性创建上所有的顶点,然后分别对各自的面进行纹理贴图显示的立方体。
public class MainActivity extends Activity { private GLSurfaceView mGLView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mGLView = new DemoGLSurfaceView(this); setContentView(mGLView); } } class DemoGLSurfaceView extends GLSurfaceView{ DomeGLRender mRenderer; public DemoGLSurfaceView(Context context) { super(context); mRenderer = new DomeGLRender(context.getResources()); this.setRenderer(mRenderer); } public boolean onTouchEvent(final MotionEvent event){ this.queueEvent(new Runnable() { @Override public void run() { if(mRenderer.bLight){ mRenderer.bLight = false; }else{ mRenderer.bLight = true; } } }); return true; } } class DomeGLRender implements Renderer { public boolean bLight = true;//是否开启灯光 private float[] vertices = { // 定义一个面的顶点坐标 -1.0f, -1.0f, 0.0f, // 0. 左-底-前 1.0f, -1.0f, 0.0f, // 1. 右-底-前 -1.0f, 1.0f, 0.0f, // 2. 左-顶-前 1.0f, 1.0f, 0.0f // 3. 右-顶-前 }; private float[] textCood = { 0.0f, 1.0f, // A. 左-下 1.0f, 1.0f, // B. 右-下 0.0f, 0.0f, // C. 左-上 1.0f, 0.0f // D. 右-上 }; float xrot,yrot; //旋转 private int[] textures = new int[1]; private FloatBuffer vertexBuffer; //顶点缓冲 private FloatBuffer textCoodBuffer; //纹理缓冲 //环境光 private float[] lightAmbient = {0.5f,0.5f,0.5f,1.0f}; private FloatBuffer AmbientBuffer; //漫射光 private float[] lightDiffuse = {1.0f,1.0f,1.0f,1.0f}; private FloatBuffer diffuseBuffer; //光源位置 private float[] lightPosition = {0.0f,0.0f,2.0f,1.0f}; private FloatBuffer positionBuffer; //图片数组 public static Bitmap[] mBitmap = new Bitmap[6]; //变换角度 private float[] angle = {0.0f, 90.0f, 180.0f, 270.0f, 90.0f, 270.0f}; //构造函数 public DomeGLRender(Resources resources){ mBitmap[0] = BitmapFactory.decodeResource(resources, R.drawable.img0); mBitmap[1] = BitmapFactory.decodeResource(resources, R.drawable.img1); mBitmap[2] = BitmapFactory.decodeResource(resources, R.drawable.img2); mBitmap[3] = BitmapFactory.decodeResource(resources, R.drawable.img0); mBitmap[4] = BitmapFactory.decodeResource(resources, R.drawable.img1); mBitmap[5] = BitmapFactory.decodeResource(resources, R.drawable.img2); //顶点 ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length * 4); vbb.order(ByteOrder.nativeOrder()); vertexBuffer = vbb.asFloatBuffer(); vertexBuffer.put(vertices); vertexBuffer.position(0); //纹理 ByteBuffer tbb = ByteBuffer.allocateDirect(textCood.length * 4); tbb.order(ByteOrder.nativeOrder()); textCoodBuffer = tbb.asFloatBuffer(); textCoodBuffer.put(textCood); textCoodBuffer.position(0); //环境光 ByteBuffer ambientbb = ByteBuffer.allocateDirect(lightAmbient.length * 4); ambientbb.order(ByteOrder.nativeOrder()); AmbientBuffer = ambientbb.asFloatBuffer(); AmbientBuffer.put(lightAmbient); AmbientBuffer.position(0); //漫射光 ByteBuffer diffusebb = ByteBuffer.allocateDirect(lightDiffuse.length * 4); diffusebb.order(ByteOrder.nativeOrder()); diffuseBuffer = diffusebb.asFloatBuffer(); diffuseBuffer.put(lightDiffuse); diffuseBuffer.position(0); //灯光位置 ByteBuffer positionbb = ByteBuffer.allocateDirect(lightPosition.length * 4); positionbb.order(ByteOrder.nativeOrder()); positionBuffer = positionbb.asFloatBuffer(); positionBuffer.put(lightPosition); positionBuffer.position(0); } @Override public void onDrawFrame(GL10 gl) { //清除颜色和深度缓存 gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT); gl.glLoadIdentity(); //启用灯光 gl.glEnable(GL10.GL_LIGHTING); //启用顶点和纹理缓存 gl.glEnableClientState(GL10.GL_VERTEX_ARRAY); gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY); //移动和旋转设置 gl.glTranslatef(0.0f, 0.0f, -6.0f); gl.glRotatef(xrot, 1.0f, 0.0f, 0.0f); gl.glRotatef(yrot, 0.0f, 1.0f, 0.0f); 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, textCoodBuffer); // 定义纹理坐标数组缓冲区 //绘制六个面,贴图 for (int i = 0; i < 6; i++) { GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, mBitmap[i], 0); gl.glPushMatrix(); if(i < 4) gl.glRotatef(angle[i], 0.0f, 1.0f, 0.0f);//y轴为中心变换 else gl.glRotatef(angle[i], 1.0f, 0.0f, 0.0f);//x轴为中心变换 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); xrot += 0.5f; yrot += 0.5f; if (!bLight) { gl.glDisable(GL10.GL_LIGHT1); } else { gl.glEnable(GL10.GL_LIGHT1); } } @Override public void onSurfaceChanged(GL10 gl, int width, int height) { //场景大小 gl.glViewport(0, 0, width, height); float ratio = (float) width / height; //投影矩阵 gl.glMatrixMode(GL10.GL_PROJECTION); //重置下 gl.glLoadIdentity(); // 设置视图区域的大小 GLU.gluPerspective(gl, 45.0f, (float)width/(float)height,0.1f,100.0f); // 选择模型观察矩阵 gl.glMatrixMode(GL10.GL_MODELVIEW); // 重置模型观察矩阵 gl.glLoadIdentity(); } @Override public void onSurfaceCreated(GL10 gl, EGLConfig config) { //透视效果 gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_FASTEST); //清屏 gl.glClearColor(0, 0, 0, 0); //启用阴影平滑 gl.glShadeModel(GL10.GL_SMOOTH); //清除深度缓存 gl.glClearDepthf(1f); //启用深度缓存 gl.glEnable(GL10.GL_DEPTH_TEST); //深度缓存模式 gl.glDepthFunc(GL10.GL_LEQUAL); //启用纹理 gl.glEnable(GL10.GL_TEXTURE_2D); //创建纹理 gl.glGenTextures(1, textures, 0); //绑定纹理 gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]); //生成纹理 GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, mBitmap[0], 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.glLightfv(GL10.GL_LIGHT1, GL10.GL_AMBIENT, AmbientBuffer); //设置漫射光 gl.glLightfv(GL10.GL_LIGHT1, GL10.GL_DIFFUSE, diffuseBuffer); //设置灯光位置 gl.glLightfv(GL10.GL_LIGHT1, GL10.GL_POSITION, positionBuffer); //启用1号灯光 gl.glEnable(GL10.GL_LIGHT1); } }源码下载:点击打开链接
相关文章推荐
- 【Android】29、常见控件的使用方法——EditText
- Android透明通知栏
- Android高效加载大图、多图解决方案,有效避免程序OOM
- Android NDK日志符号化 查找crash原因
- Android开发之AIDL实现远程服务进程通信(IPC)
- Android中GLSurfaceView截图
- recylerview的使用
- Android apk dex与odex
- android CoordinatorLayout使用
- 文章标题
- Android之JNI NDK错误 No JNI_OnLoad found in /data/data/
- android权限大全
- 我学过的android-3缓存技术
- Android 系统API实现数据库的增删改查和SQLite3工具的使用
- Android中RecyclerView布局代替GridView实现类似支付宝的界面
- Android 官方推荐 : DialogFragment 创建对话框
- android 关于无法在onCreate方法中显示popUpWindow的解决方案
- 说说Android的广播(1) - 普通广播,有序广播和粘性广播
- Android Canvas绘图详解(图文)
- Android验证码时间倒计时