zoukankan      html  css  js  c++  java
  • OpenGL 纹理贴图

    前一节实例代码中有个贴图操作。

    今天就简单说明一下纹理贴图。。。

    为了使用纹理贴图。我们首先需要启用纹理贴图功能。

    我们可以在Renderer实现的onSurfaceCreated中定义启用:

    // 启用2D纹理贴图
    gl.glEnable(GL10.GL_TEXTURE_2D);

    那么接下来我们需要准备作为纹理贴图的图片。

    放在res/drawable目录下就行。

    那么我们需要把作为纹理贴图的图片给加载进来。如下:

    private void loadTexture(GL10 gl) {
                    Bitmap bitmap = null;
                    try {
                        // 加载位图
                        bitmap = BitmapFactory.decodeResource(context.getResources(),
                                R.drawable.sand);
                        int[] textures = new int[1];
                        // 指定生成N个纹理(第一个参数指定生成1个纹理),
                        // textures数组将负责存储所有纹理的代号。
                        gl.glGenTextures(1, textures, 0);
                        // 获取textures纹理数组中的第一个纹理
                        texture = textures[0];
                        // 通知OpenGL将texture纹理绑定到GL10.GL_TEXTURE_2D目标中
                        gl.glBindTexture(GL10.GL_TEXTURE_2D, texture);
                        // 设置纹理被缩小(距离视点很远时被缩小)时候的滤波方式
                        gl.glTexParameterf(GL10.GL_TEXTURE_2D,
                                GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_NEAREST);
                        // 设置纹理被放大(距离视点很近时被方法)时候的滤波方式
                        gl.glTexParameterf(GL10.GL_TEXTURE_2D,
                                GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);
                        // 设置在横向、纵向上都是平铺纹理
                        gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S,
                                GL10.GL_REPEAT);
                        gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T,
                                GL10.GL_REPEAT);
                        // 加载位图生成纹理
                        GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0);
                    } finally {
                        // 生成纹理之后,回收位图
                        if (bitmap != null)
                            bitmap.recycle();
                    }
                }

     在这里比较不明白的应该是

    // textures数组将负责存储所有纹理的代号。
    gl.glGenTextures(1, textures, 0);

    在绘制动画时,由于每秒钟需要将画面绘制数十次,因此就会反复载入纹理,这对计算机是非常大的负担。因此,需要有一种机制,能够在不同的纹理之间进行快速的切换。

    我们可以把每一幅纹理(包括纹理的像素数据、纹理大小等信息,也包括了前面所讲的纹理参数)放到一个纹理对象中,通过创建多个纹理对象来达到同时保存多幅纹理的目的。

    这样一来,在第一次使用纹理前,把所有的纹理都载入,然后在绘制时只需要指明究竟使用哪一个纹理对象就可以了。

    使用一个正整数来作为纹理对象的编号。在使用前,可以调用glGenTextures来分配纹理对象:

    *第一个参数:是分配多少个纹理编号(例中1个)

    *第二个参数:是存放编号单元。

    零是一个特殊的纹理对象编号,表示“默认的纹理对象”,在分配正确的情况下,glGenTextures不会分配这个编号。与glGenTextures对应的是glDeleteTextures,用于销毁一个纹理对象。
     

    接下来就是指定当前所使用的纹理对象,即绑定对象:

    // 通知OpenGL将texture纹理绑定到GL10.GL_TEXTURE_2D目标中
    gl.glBindTexture(GL10.GL_TEXTURE_2D, texture);

    其他的看看注释就行了。

    那么具体在什么位置进行贴图,那么久需要看如下代码了:

    private FloatBuffer cubeTexturesBuffer;
    //
    定义纹理贴图的座标数据 private float[] cubeTextures = { 1.0000f, 1.0000f, 1.0000f, 0.0000f, 0.0000f, 0.0000f, 0.0000f, 0.0000f, 0.0000f, 1.0000f, 1.0000f, 1.0000f, 0.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.0000f, 1.0000f, 0.0000f, 0.0000f, 0.0000f, 0.0000f, 1.0000f, 0.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.0000f, 1.0000f, 0.0000f, 0.0000f, 0.0000f, 0.0000f, 1.0000f, 0.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.0000f, 1.0000f, 0.0000f, 0.0000f, 0.0000f, 0.0000f, 1.0000f, 0.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.0000f, 1.0000f, 0.0000f, 0.0000f, 0.0000f, 0.0000f, 1.0000f, 0.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.0000f, 1.0000f, 0.0000f, 0.0000f, 0.0000f, 0.0000f, 1.0000f }; // 将立方体的纹理贴图的座标数据包装成FloatBuffer ByteBuffervbb = ByteBuffer.allocateDirect(cubeTextures.length * 4); vbb.order(ByteOrder.nativeOrder()); cubeTexturesBuffer = vbb.asFloatBuffer(); cubeTexturesBuffer.put(cubeTextures); cubeTexturesBuffer.position(0);

    光有数据也比行我们需要把这些坐标数据加载进来。那么首先我们可以在onDrawFrame启用贴图数组然后设置:

    // 启用贴图座标数组数据
    gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
    // 设置贴图的的座标数据
    gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, cubeTexturesBuffer);
  • 相关阅读:
    主机的IOPS需求转换成硬盘实际IOPS负载
    IT安全运维职责
    IT应用运维职责
    存储RAID 选择策略
    交换机接口下错包计数,哪些是属于物理链路(包括本端设备和对端设备硬件问题)引起的
    华为交换机SNMP配置
    c# 位与运算符&简单实现复选框功能【实际应用】
    centos7 安装谷歌浏览器教程
    centos7下 Consul安装
    .netcore3.1 获取请求头header中认证信息并调用其它接口
  • 原文地址:https://www.cnblogs.com/hongguang-kim/p/5653275.html
Copyright © 2011-2022 走看看