Android OpenGL ES 绘图 -- 材质渲染

OpenGL 绘图 – 材质渲染

注:参考:http://wiki.jikexueyuan.com/project/opengl-es-basics/texture-rendering.html

创建 Bitmap 对象

使用材质渲染,首先需要构造用来渲染的 Bitmap 对象,Bitmap 对象可以从资源文件中读取或是从网路下载或是使用代码构造。为简单起见,本例从资源中读取,在Renderer类中创建设置Bitmap方法(需在setRenderer前调用):

    public void setBitmap(Bitmap bitmap) {
        this.bitmap = bitmap;
    }

要注意的是,有些设备对使用的 Bitmap 的大小有要求,要求 Bitmap 的宽度和长度为 2 的几次幂(1,2,4,8,16,32,64.。。。),如果使用不和要求的 Bitmap 来渲染,可能只会显示白色。

创建材质(Generating a texture)

下一步使用 OpenGL 库创建一个材质(Texture),首先是获取一個 Texture Id。

// Create an int array with the number of textures we want,
// in this case 1.
int[] textures = new int[1];
// Tell OpenGL to generate textures.
gl.glGenTextures(1, textures, 0);  

textures 中存放了创建的 Texture ID,使用同样的 Texture Id ,也可以来刪除一个 Texture:

// Delete a texture.
gl.glDeleteTextures(1, textures, 0)  

有了 Texture Id 之后,就可以通知 OpenGL 库使用这个 Texture:

gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]);  

设置 Texture 参数 glTexParameter

下一步需要給 Texture 填充设置参数,用来渲染的 Texture 可能比要渲染的区域大或者小,这是需要设置 Texture 需要放大或是缩小时 OpenGL 的模式:

// Scale up if the texture if smaller.
gl.glTexParameterf(GL10.GL_TEXTURE_2D,
 GL10.GL_TEXTURE_MAG_FILTER,
 GL10.GL_LINEAR);
// scale linearly when image smalled than texture
gl.glTexParameterf(GL10.GL_TEXTURE_2D,
 GL10.GL_TEXTURE_MIN_FILTER,
 GL10.GL_LINEAR);  

常用的两种模式为 GL10.GL_LINEAR 和 GL10.GL_NEAREST。
需要比较清晰的图像使用 GL10.GL_NEAREST;
而使用 GL10.GL_LINEAR 则会得到一个较模糊的图像;

定义 UV 坐标

UV Mapping 指将 Bitmap 的像素映射到 Mesh 上的顶点。UV 坐标定义为左上角(0,0),右下角(1,1)(因为使用的 2D Texture),下图坐标显示了 UV 坐标,右边為我们需要染色的平面的顶点順序:

为了能正确的匹配,需要把 UV 坐标中的(0,0)映射到顶点 0,(0,1)映射到顶点 2 等等。

        float textureCoordinates[] = {0.0f, 0.0f,
                0.0f, 1.0f,
                1.0f, 1.0f,
                1.0f, 0.0f};


將使用一些不存在的 Texture 去渲染平面(UV 坐标为 0,0-1,1 而 (0,0)-(2,2)定义超过 UV 定义的大小),这时需要告诉 OpenGL 库如何去渲染这些不存在的 Texture 部分。
有两种設置

  • GL_REPEAT 重复 Texture。
  • GL_CLAMP_TO_EDGE 只靠边线复制一次。

本例使用如下配置:

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);  

然后是将 Bitmap 资源和 Texture 绑定起來:

GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0);  

为了能够使用上面定义的 Texture,需要创建一 Buffer 來存储 UV 坐标:

        ByteBuffer byteBuf = ByteBuffer.allocateDirect(textureCoordinates.length * 4);
        byteBuf.order(ByteOrder.nativeOrder());
        FloatBuffer textureBuffer = byteBuf.asFloatBuffer();
        textureBuffer.put(textureCoordinates);
        textureBuffer.position(0);

渲染

        //开启2D材质渲染
        gl.glEnable(GL10.GL_TEXTURE_2D);
        //开启材质渲染UV坐标管道
        gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
        //开启点坐标管道
        gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
        //开启点颜色管道
        gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
        //传入点坐标
        gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer);
        //传入点颜色数组
        gl.glColorPointer(4, GL10.GL_FLOAT, 0, colorBuffer);
        //传入UV坐标
        gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, textureBuffer);
        //根据点与绘线顺序绘面
        gl.glDrawElements(GL10.GL_TRIANGLES, indices.length,
                GL10.GL_UNSIGNED_SHORT, indexBuffer);
        //关闭点颜色管道
        gl.glDisableClientState(GL10.GL_COLOR_ARRAY);
        //关闭点坐标管道
        gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
        //关闭材质渲染UV坐标管道
        gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
        //关闭2D材质渲染
        gl.glDisable(GL10.GL_TEXTURE_2D);
        // Delete a texture.(如果不删除,如果不断绘画,应用所占运存会不断增加)
        gl.glDeleteTextures(1, textures, 0);
    }

Demo

本例代码同样在上次中更改
在drawREC中

添加UV坐标
        float textureCoordinates[] = {0.0f, 0.0f,
                0.0f, 1.0f,
                1.0f, 1.0f,
                1.0f, 0.0f};
        ByteBuffer byteBuf = ByteBuffer.allocateDirect(textureCoordinates.length * 4);
        byteBuf.order(ByteOrder.nativeOrder());
        FloatBuffer textureBuffer = byteBuf.asFloatBuffer();
        textureBuffer.put(textureCoordinates);
        textureBuffer.position(0);
生成材质并绑定
            int[] textures = new int[1];
            // Tell OpenGL to generate textures.
            gl.glGenTextures(1, textures, 0);
            gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]);
配置材质属性
            // Scale up if the texture if smaller.
            gl.glTexParameterf(GL10.GL_TEXTURE_2D,
                    GL10.GL_TEXTURE_MAG_FILTER,
                    GL10.GL_LINEAR);
            // scale linearly when image smalled than texture
            gl.glTexParameterf(GL10.GL_TEXTURE_2D,
                    GL10.GL_TEXTURE_MIN_FILTER,
                    GL10.GL_LINEAR);
            //重复Texture去渲染不存在的Texture部分
            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);
把Bitmap与Texture绑定起来
            //将 Bitmap 资源和 Texture 绑定起來:
            GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0);
绘图
        //开启2D材质渲染
        gl.glEnable(GL10.GL_TEXTURE_2D);
        //开启材质渲染UV坐标管道
        gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
        //开启点坐标管道
        gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
        //开启点颜色管道
        gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
        //传入点坐标
        gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer);
        //传入点颜色数组
        gl.glColorPointer(4, GL10.GL_FLOAT, 0, colorBuffer);
        //传入UV坐标
        gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, textureBuffer);
        //根据点与绘线顺序绘面
        gl.glDrawElements(GL10.GL_TRIANGLES, indices.length,
                GL10.GL_UNSIGNED_SHORT, indexBuffer);
        //关闭点颜色管道
        gl.glDisableClientState(GL10.GL_COLOR_ARRAY);
        //关闭点坐标管道
        gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
        //关闭材质渲染UV坐标管道
        gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
        //关闭2D材质渲染
        gl.glDisable(GL10.GL_TEXTURE_2D);
        // Delete a texture.(如果不删除,如果不断绘画,应用所占运存会不断增加)
        gl.glDeleteTextures(1, textures, 0);

效果图:
这里写图片描述
代码:http://download.csdn.net/download/z896435317/9960486

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值