我使用以下函数来加载纹理
public static int loadTexture(Bitmap bmp)
{
final int[] textureHandle = new int[1];
GLES20.glGenTextures(1, textureHandle, 0);
if (textureHandle[0] != 0)
{
// Bind to the texture in OpenGL
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureHandle[0]);
// Set filtering
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR);
//GLES20.glGenerateMipmap(textureHandle[0]);
//adapt texture to POT
int adaptedWidth= (int) Math.pow(2,Math.ceil(Math.log(bmp.getWidth())/Math.log(2d)));
int adaptedHeight= (int) Math.pow(2,Math.ceil(Math.log(bmp.getHeight())/Math.log(2d)));
Log.d("texture",adaptedWidth+","+adaptedHeight);
Bitmap tmp = Bitmap.createScaledBitmap(bmp, adaptedWidth, adaptedHeight, false);
Log.d("asize",tmp.getWidth()+","+tmp.getHeight());
// Load the bitmap into the bound texture.
GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, tmp, 0);
//GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bmp, 0);
tmp.recycle();
// Recycle the bitmap, since its data has been loaded into OpenGL.
//bmp.recycle();
}
if (textureHandle[0] == 0)
{
throw new RuntimeException("Error loading texture.");
}
return textureHandle[0];
}
我得到14-17 fps的代码。如果我直接加载我的位图(非POT)而不适应POT.FPS跳转到28-30.Hovever我认为POT纹理应该比非POT工作更快。对此有解释吗?
UPD:渲染代码:
@Override
public void onDrawFrame(GL10 gl) {
//curScale=modelMatrix[SCALE_X];
TimeMeasurer.reset();
long curTS= SystemClock.uptimeMillis();
long frameRenderTime=curTS-ts;
//Log.d("renderer","FPS:"+1000.0/frameRenderTime);
Log.d("renderer","frame render time:"+frameRenderTime);
ts=curTS;
GLES20.glClear(GLES20.GL_DEPTH_BUFFER_BIT | GLES20.GL_COLOR_BUFFER_BIT);
if (piecesMesh!=null) {
Matrix.setIdentityM(MVPMatrix,0);
Matrix.multiplyMM(MVPMatrix,0,projMatrix,0,modelMatrix,0);
drawPassivePieces();
drawActivePieces();
if (helper!=null) {
drawHelper();
}
}
TimeMeasurer.measure("onDrawFrame execution time:");
}
private void drawPassivePieces() {
//shadows
shadowProgram.useProgram();
shadowProgram.setUniforms(MVPMatrix,textureMaskId);
shadowMesh.bindPieceData(shadowProgram,false);
shadowMesh.drawPieces(false);
shadowMesh.disableAttributes(shadowProgram);
//pieces
piecesProgram.useProgram();
piecesProgram.setUniforms(MVPMatrix, textureImageId, textureMaskId);
piecesMesh.bindPieceData(piecesProgram,false);
piecesMesh.drawPieces(false);
piecesMesh.disableAttributes(piecesProgram);
}
private void drawActivePieces() {
//shadows
shadowProgram.useProgram();
shadowProgram.setUniforms(MVPMatrix,textureMaskId);
shadowMesh.bindPieceData(shadowProgram,true);
shadowMesh.drawPieces(true);
shadowMesh.disableAttributes(shadowProgram);
//pieces
piecesProgram.useProgram();
piecesProgram.setUniforms(MVPMatrix, textureImageId, textureMaskId);
piecesMesh.bindPieceData(piecesProgram,true);
piecesMesh.drawPieces(true);
piecesMesh.disableAttributes(piecesProgram);
}
public void drawHelper() {
helperProgram.useProgram();
helper.bindData(helperProgram);
helper.draw();
helper.disableAttributes(helperProgram);
}
答案 0 :(得分:0)
使用POT纹理有很大的优势。在OpenGLES 2.0中,它们允许您使用mipmap和有用的纹理寻址模式,如重复。您还可以更有效地利用内存,因为许多实现分配内存,就像您的纹理无论如何都是POT一样。
然而,在这种情况下你只需要采用非POT纹理并将其放大,我预计性能会稍差一些。你错过了巨大的潜在胜利,因为你没有使用mipmap。通过使用更大的纹理,您只需要更多GPU的纹理缓存,因为图像的有用部分现在比以前更加分散在内存中。
另一种看待它的方法是,在没有mipmapping的情况下,大纹理的表现会比小纹理差,而你的重新缩放过程只会让你的纹理更大。
我很惊讶差异是如此明显 - 你确定你的重新缩放代码路径没有做任何意外的事情,比如调整太大,或选择不同的纹理格式或过滤模式吗?
答案 1 :(得分:0)
如果没有详细的绩效分析,那么除了推测之外,其实不可能做得更多。
一个可能的原因是您的渲染受到纹理采样的内存带宽的限制。如果使纹理变大,访问的内存总量会更大,从而导致速度减慢。
或者,与上述内容非常相关,如果采样的纹理像素在内存中展开得更远,则纹理采样的缓存命中率会下降,这会在您对纹理进行放大时发生。降低缓存命中率意味着性能降低。
你真的不应该人为地使纹理大于必要,除非由于ES 2.0中有限的NPOT支持而需要它,并且你使用的硬件不会宣传OES_texture_npot扩展。我怀疑是否有人制造了长时间喜欢POT纹理的硬件。