7.6 绘制纹理(Drawing Our Texture)
现在我们已经把顶点数据与操作顶点数据的类解耦,接下来修改下render类以绘制纹理;打开AirHockeyRenderer并把除了onSurfaceChanged()以外的其它都部分删除,并添加如下的成员与构造函数:
//AirHockeyTextured/src/com/airhockey/android/AirHockeyRenderer.java
private final Context context;
private final float[] projectionMatrix = new float[16];
private final float[] modelMatrix = new float[16];
private Table table;
private Mallet mallet;
private TextureShaderProgram textureProgram;
private ColorShaderProgram colorProgram;
private int texture;
public AirHockeyRenderer(Context context) {
this.context = context;
}
我们保留了context及矩阵变量并增加了一些其它变量;此时构造函数仅仅只是保留了context的一个引用。
7.6.1 初始化变量(Initializing Our Variables)
在onSurfaceCreated()函数中添加如下初始化变量的代码:
//AirHockeyTextured/src/com/airhockey/android/AirHockeyRenderer.java
@Override
public void onSurfaceCreated(GL10 glUnused, EGLConfig config) {
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
table = new Table();
mallet = new Mallet();
textureProgram = new TextureShaderProgram(context);
colorProgram = new ColorShaderProgram(context);
texture = TextureHelper.loadTexture(context, R.drawable.air_hockey_surface);
}
这里把颜色清除为黑色,初始化顶点数据及着色器程序并使用相关辅助类加载纹理。
7.6.2 使用纹理进行绘制(Drawing with the Texture)
onSurfaceChanged()方法并不需要修改,现在把onDrawFrame()修改为如下:
//AirHockeyTextured/src/com/airhockey/android/AirHockeyRenderer.java
@Override
public void onDrawFrame(GL10 glUnused) {
// Clear the rendering surface.
glClear(GL_COLOR_BUFFER_BIT);
// Draw the table.
textureProgram.useProgram();
textureProgram.setUniforms(projectionMatrix, texture);
table.bindData(textureProgram);
table.draw();
// Draw the mallets.
colorProgram.useProgram();
colorProgram.setUniforms(projectionMatrix);
mallet.bindData(colorProgram);
mallet.draw();
}
清除surface然后绘制桌面,首先调用textureProgram.useProgram()告诉OpenGL使用该程序进行绘制,然后传入uniform类型常量调用函数textureProgram.setUniforms(),下一步调用函数table.bindData()把顶点数据与着色器程序绑定,最后调用table.draw()绘制桌面。
最后重复同样的过程使用颜色着色器绘制小球。
7.6.3 运行程序(Running the Program and Seeing the Results)
最后运行程序你将会看到如下图所示的效果,但是即使OpenGL 没有报错你也可能看到类似E/IMGSRV(20095): :0: HardwareMipGen: Failed to generate texture mipmap levels (error=3),这样的log信息;这意味着你的设备并不支持非正方形纹理(调用函数glGenerateMipMap())。
一个简单的修复办法是把纹理压缩成正方形;由于该纹理应用于矩形surface因此它将会拉伸且最终效果仍然看上去与上面的效果类似。
最后附上本章源代码(点击下载)