我正在制作我在 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,或者某些仅影响 Desire S 的配置/设置,但我似乎无法找出是什么,是否有人有任何想法或建议如何获得它再次正确渲染?
PS我看到的逻辑是,当我在开始时(和结束时)渲染我的红色块(效果)时,它会以某种方式交换背景纹理,只要我不再用那个红色块纹理渲染任何三角形,背景再次正确渲染。我在粒子上看到的一样,渲染它们会弄乱文本。这里奇怪的是粒子纹理与我的背景在同一个纹理上,所以在没有粒子的游戏过程中它已经从那个纹理中绘制了。
此外,它只发生在我的游戏/菜单/部件/等所有部分的这两个地方/实例上。