2016-07-01 5 views
0

Zunächst einmal, sorry für mein schlechtes Englisch.Android OpenGL ES - Kann nicht mehr als 9 Texturen auf einigen Geräten zu binden

Ich mache 2D-Szene für meine Anwendung. Es gibt 13 Texturen in meiner Szene, also habe ich diese Texturen mit folgendem Code gebunden. (I fest einprogrammiert es, weil ich es bin Tests)

//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(); 

Und dann Getestet habe ich es auf drei Geräte, Samsung Galaxy S3, Note 4 und S5.

Hinweis 4 und S5 rendert richtig, alle 13 von ihnen. Aber Galaxy S3 rendert nur 9 Texturen, nach 10. Textur rendert es textures [0] 's Textur.

Da Note 4 und S5 perfekt läuft, dachte ich, dass mein Code kein Problem hat. Ich habe es stundenlang gegoogelt, aber ich kann nicht einmal herausfinden, was das Problem ist.

Jede Hilfe wäre willkommen. Danke fürs Lesen.

- für weitere Details, füge ich meinen Shader und Rendering-Code.

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); 
} 

Antwort

0

Von Ihrem Rendering-Code, nehme ich an, dass Sie jede Textur auf seine eigene Textur-Einheit gebunden:

Wahrscheinlich Sie die erlaubte Anzahl von Texturen überschreiten, die zur gleichen Zeit benutzt werden kann. In OpenGL ES kleiner oder gleich 2.0 ist es nur garantiert, dass 8 Textureinheiten gleichzeitig verwendet werden können, obwohl es mehr geben kann. Sie können das Limit mit glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, ...); abfragen.

Was Sie in Ihrer Anwendung tun können (und da Sie nur eine Textur gleichzeitig verwenden), ist, jede Textur an z. B. TEXTURE_UNIT0 zu binden, anstatt jede Textur ihrer eigenen Einheit zuzuweisen. Der Zeichnungscode sieht dann so aus:

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); 
Verwandte Themen