2016-07-01 1 views
0

Прежде всего, извините за мой плохой английский.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); 
} 

ответ

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); 
Смежные вопросы