首先,抱歉我的英语不好。
我正在为我的应用程序制作2D场景。我的场景中有13个纹理,所以我通过以下代码绑定这些纹理。 (我硬编码因为我正在测试它)
//Prepare texture bitmap
BitmapFactory.Options bfo = new BitmapFactory.Options();
Bitmap bmp = BitmapFactory.decodeResource(getContext().getResources(), R.drawable.scene02_bg, bfo);
//Bind Texture
int[] texturenames = new int[13];
GLES20.glGenTextures(13, texturenames, 0);
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, texturenames[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);
//Load Texture
GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bmp, 0);
//Recycle bitmap
bmp.recycle();
//for second texture
bmp = BitmapFactory.decodeResource(getContext().getResources(), R.drawable.scene02_campfire, bfo);
GLES20.glActiveTexture(GLES20.GL_TEXTURE1);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, texturenames[1]);
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);
GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bmp, 0);
bmp.recycle();
//............
//............
//............
bmp = BitmapFactory.decodeResource(getContext().getResources(), R.drawable.scene02_tree09, bfo);
GLES20.glActiveTexture(GLES20.GL_TEXTURE12);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, texturenames[12]);
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);
GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bmp, 0);
bmp.recycle();
然后,我在三个设备上测试了它,三星Galaxy S3,Note 4和S5。
注4和S5正确渲染,全部13个。但是Galaxy S3只渲染了9个纹理,在第10个纹理之后,渲染了纹理名称[0]的纹理。
由于Note 4和S5完美运行,我认为我的代码没有问题。我用Google搜索了几个小时,但我甚至无法确定这有什么问题。
任何帮助将不胜感激。谢谢你的阅读。
- 有关更多详细信息,请附上我的着色器和渲染代码。
public static final String VERTEXSHADER_TEXTURE =
"uniform mat4 uMVPMatrix;" +
"attribute vec4 vPosition;" +
"attribute vec2 a_texCoord;" +
"varying vec2 v_texCoord;" +
"void main() {" +
" gl_Position = uMVPMatrix * vPosition;" +
" v_texCoord = a_texCoord;" +
"}";
public static final String FRAGMENTSHADER_TEXTURE =
"precision mediump float;" +
"varying vec2 v_texCoord;" +
"uniform sampler2D s_texture;" +
"void main() {" +
" gl_FragColor = texture2D( s_texture, v_texCoord );" +
"}";
public void Draw(float[] mvpMatrix){
int mPositionHandle, mMVPMatrixHandle;
float[] mvp;
mvp = mvpMatrix.clone();
Matrix.setIdentityM(mModelMatrix, 0);
Matrix.scaleM(mModelMatrix, 0, mScale, mScale, 1);
Matrix.translateM(mModelMatrix, 0, mPositionX, mPositionY, mPositionZ);
Matrix.setRotateM(mRotationMatrix, 0, mAngle, 0, 0, -1f);
mTempMatrix = mModelMatrix.clone();
Matrix.multiplyMM(mModelMatrix, 0, mTempMatrix, 0, mRotationMatrix, 0);
mTempMatrix = mvp.clone();
Matrix.multiplyMM(mvp, 0, mTempMatrix, 0, mModelMatrix, 0);
GLES20.glUseProgram(mTextureShaderProgram);
/*Setup vertex*/
mPositionHandle = GLES20.glGetAttribLocation(mTextureShaderProgram, "vPosition");
GLES20.glEnableVertexAttribArray(mPositionHandle);
GLES20.glVertexAttribPointer(mPositionHandle, COORDS_PER_VERTEX, GLES20.GL_FLOAT, false,
vertexStride, vertexBuffer);
/*Setup camera view*/
mMVPMatrixHandle = GLES20.glGetUniformLocation(mTextureShaderProgram, "uMVPMatrix");
GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, mvp, 0);
//Setup Texture
int texCoordHandle = GLES20.glGetAttribLocation(mTextureShaderProgram, "a_texCoord");
GLES20.glEnableVertexAttribArray(texCoordHandle);
GLES20.glVertexAttribPointer(texCoordHandle, 2, GLES20.GL_FLOAT, false, 0, uvBuffer);
int samplerHandle = GLES20.glGetUniformLocation(mTextureShaderProgram, "s_texture");
GLES20.glUniform1i(samplerHandle, textureIndex);
/*Draw*/
GLES20.glDrawElements(GLES20.GL_TRIANGLES, drawOrder.length, GLES20.GL_UNSIGNED_SHORT, indexBuffer);
GLES20.glDisableVertexAttribArray(mPositionHandle);
}
答案 0 :(得分:0)
从渲染代码中,我假设你将每个纹理绑定到它自己的纹理单元:
最有可能的是,你超过了可以同时使用的允许纹理数量。在OpenGL ES小于或等于2.0时,只保证可以同时使用8个纹理单元,尽管可以有更多。您可以使用glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, ...);
查询限制。
你可以在你的应用程序中做什么(并且因为你一次只使用一个纹理),就是将每个纹理重新绑定到例如TEXTURE_UNIT0,而不是将每个纹理分配给它自己的单元。然后,绘图代码如下所示:
int samplerHandle = GLES20.glGetUniformLocation(mTextureShaderProgram, "s_texture");
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, texturenames[textureIndex]);
GLES20.glUniform1i(samplerHandle, 0);
GLES20.glDrawElements(GLES20.GL_TRIANGLES, drawOrder.length,
GLES20.GL_UNSIGNED_SHORT, indexBuffer);