zoukankan      html  css  js  c++  java
  • 绘制立方体和单个的矩阵,并映射纹理图像

    绘图有很多需要注意的地方,直接提出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);
     
    }
     
     
    }
    立方体生成多个纹理图的效果图:
     
  • 相关阅读:
    php----爬虫(爬取豆瓣演员信息,搜索页)遇到的问题
    python-写爬虫时遇到的问题 TimeoutError: [WinError 10060]
    聚沙成塔
    买手机,继续纠结中
    问题不绕弯,死磕
    死磕,死磕死磕
    学而不践则罔
    越是忙的时候,兴趣越多
    周末小总结
    幸福和需求
  • 原文地址:https://www.cnblogs.com/bokeofzp/p/5967627.html
Copyright © 2011-2022 走看看