我正在制作一款我在Nexus 4上开发的游戏,它运行良好且没有任何问题。我在索尼的Xperia U上测试过它(对于这个问题)它运行良好。 然而问题是欲望S(使用相同的代码)
当我开始实际的游戏时,我有这个应该渲染的背景纹理,但是大约一秒左右,它会采用错误的纹理。看效果:
问题交换的图像:
左图是出了什么问题,正确的图片是它应该是什么样的(不是完全相同的时间,但它是为了我的问题的可视化)。
它需要分配给GLES20.GL_TEXTURE4的纹理,它应该采用GLES20.GL_TEXTURE0。
在我进入代码之前,在游戏过程中会发生同样的事情,每当渲染粒子时,我的文本(也是纹理)都会与不同的纹理交换。我的粒子消失的那一刻,文本再次正确呈现。
问题交换的图像:
在这个例子中,它似乎采用了保持背景的纹理,但它是随机的,因为我确实记得只看到字符,但后面是黑色背景,没有透明度。粒子和文本引擎使用相同的ShaderProgram,但背景却没有,但为了完整性,我的着色器:
public static final String vertexShaderCodeTC =
"uniform mat4 uMVPMatrix;" +
"attribute vec4 vPosition;" +
"attribute vec4 a_Color;" +
"attribute vec2 a_texCoord;" +
"varying vec4 v_Color;" +
"varying vec2 v_texCoord;" +
"void main() {" +
" gl_Position = uMVPMatrix * vPosition;" +
" v_texCoord = a_texCoord;" +
" v_Color = a_Color;" +
"}";
public static final String fragmentShaderCodeTC =
"precision mediump float;" +
"varying vec4 v_Color;" +
"varying vec2 v_texCoord;" +
"uniform sampler2D s_texture;" +
"void main() {" +
" gl_FragColor = texture2D( s_texture, v_texCoord ) * v_Color;" +
" gl_FragColor.rgb *= v_Color.a;" +
"}";
现在这是我的渲染代码:
int mPositionHandle = GLES20.glGetAttribLocation(riGraphicTools.ShaderProgram, "vPosition");
riGlobal.checkGlError("glGetAttribLocation | vposition |");
// Enable a handle to the triangle vertices
GLES20.glEnableVertexAttribArray(mPositionHandle);
riGlobal.checkGlError("glEnableVertexAttribArray");
// Prepare the background coordinate data
GLES20.glVertexAttribPointer(mPositionHandle, 3,
GLES20.GL_FLOAT, false,
0, vertexBuffer);
riGlobal.checkGlError("glVertexAttribPointer");
int mTexCoordLoc = GLES20.glGetAttribLocation(riGraphicTools.ShaderProgram, "a_texCoord" );
riGlobal.checkGlError("glGetAttribLocation | a_texCoord");
// Prepare the texturecoordinates
GLES20.glVertexAttribPointer ( mTexCoordLoc, 2, GLES20.GL_FLOAT,
false,
0, textureBuffer);
riGlobal.checkGlError("glVertexAttribPointer");
GLES20.glEnableVertexAttribArray ( mPositionHandle );
riGlobal.checkGlError("glEnableVertexAttribArray");
GLES20.glEnableVertexAttribArray ( mTexCoordLoc );
riGlobal.checkGlError("glEnableVertexAttribArray");
// get handle to shape's transformation matrix
int mtrxhandle = GLES20.glGetUniformLocation(riGraphicTools.ShaderProgram, "uMVPMatrix");
riGlobal.checkGlError("glGetUniformLocation");
// Apply the projection and view transformation
GLES20.glUniformMatrix4fv(mtrxhandle, 1, false, m, 0);
riGlobal.checkGlError("glUniformMatrix4fv");
int mSamplerLoc = GLES20.glGetUniformLocation (riGraphicTools.ShaderProgram, "s_texture" );
riGlobal.checkGlError("glGetUniformLocation");
// Set the sampler texture unit to 0
GLES20.glUniform1i ( mSamplerLoc, riGlobal.get().getThemeStateOne());
riGlobal.checkGlError("glUniform1i");
// Draw the triangle
GLES20.glDrawElements(GLES20.GL_TRIANGLES, GameBackground.indices.length,
GLES20.GL_UNSIGNED_SHORT, drawListBuffer);
riGlobal.checkGlError("glDrawElements");
// Disable vertex array
GLES20.glDisableVertexAttribArray(mPositionHandle);
riGlobal.checkGlError("glDisableVertexAttribArray");
GLES20.glDisableVertexAttribArray(mTexCoordLoc);
riGlobal.checkGlError("glDisableVertexAttribArray");
当我调试时,我的主题函数返回正确的纹理值,因此它应该渲染我的背景(就像在所有其他设备上一样),但不知何故它不在Desire S上。
这可能不是你需要的所有代码,但我不确切知道你需要什么,发布我的整个应用程序似乎有点矫枉过正,所以请问我会解释等等。
我已经在多个设备上测试了这个,所以它看起来真的只是Desire S,或者只是影响欲望S的一些配置/设置但我似乎无法找出什么,有没有人有任何想法或建议如何让它再次正确渲染?
P.S。我看到的逻辑是,当我在开始时渲染我的红色块(效果)时(以此结束)它以某种方式交换背景纹理,只要我不再渲染具有该红色块纹理的任何三角形,背景渲染再次正确。同样我看到粒子,使它们混淆了文本。这里奇怪的是,粒子纹理与我的背景在同一个纹理上,所以在没有粒子的游戏过程中,它已经从那个纹理中绘制出来。
此外,它只发生在我的游戏/菜单/部件等的所有部分中的那两个地方/实例上。
答案 0 :(得分:0)
解决了这个问题,这是GPU驱动程序软件中的一个错误,textureunit id只占用一次,更多信息:http://androidblog.reindustries.com/hack-bad-gpu-fix-not-using-correct-texture-opengl/