Прежде всего, извините за мой плохой английский.Android OpenGL ES - Невозможно связать более 9 текстур на некоторых устройствах
Я делаю 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();
И потом, я проверил это на трех устройствах, Samsung Galaxy S3, примечание 4, и S5.
Примечание 4 и S5 правильно отображаются, все 13 из них. Но Galaxy S3 отображает только 9 текстур, после 10-й текстуры он отображает текстуру texturenames [0].
Поскольку примечание 4 и S5 отлично работают, я думал, что у моего кода нет проблем. Я часами гулял по нему, но я даже не могу понять, что с этим связано.
Любая помощь будет оценена по достоинству. Спасибо за чтение.
- Для получения более подробной информации, я прикрепляю свой шейдер и код рендеринга.
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);
}