Android OpenGLES 2.0加载更多纹理

时间:2014-07-15 21:40:13

标签: android opengl-es opengl-es-2.0

我想在OpenGL中加载多个纹理并使用它们。

这是TextureLoader,我认为它正确加载了idx位置的纹理。

public  int[] texture = new int[10];
public  int loadTexture(Context context, int resource,int idx){

    GLES20.glGenTextures(idx, texture, 0);

    BitmapFactory.Options bo = new BitmapFactory.Options();
    Bitmap tex = BitmapFactory.decodeResource(context.getResources(), resource, bo);

    GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST);
    GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_NEAREST);
    GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE);
    GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE);

    GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, tex, 0);
    tex.recycle();

    if(texture[idx] == 0){
        // Displays error
    }
    return texture[idx];

}

这是我的渲染,我不知道如何选择加载的纹理。

      int mPositionHandle = 
            GLES20.glGetAttribLocation(riGraphicTools.sp_Image, "vPosition");

      GLES20.glEnableVertexAttribArray(mPositionHandle);

      GLES20.glVertexAttribPointer(mPositionHandle, 3,
                                     GLES20.GL_FLOAT, false,
                                     0, vertexBuffer);

      int mTexCoordLoc = GLES20.glGetAttribLocation(riGraphicTools.sp_Image, 
                           "a_texCoord" );

      GLES20.glEnableVertexAttribArray ( mTexCoordLoc );

      // Prepare the texturecoordinates
      GLES20.glVertexAttribPointer ( mTexCoordLoc, 2, GLES20.GL_FLOAT,
                    false,
                    0, uvBuffer);

      int mtrxhandle = GLES20.glGetUniformLocation(riGraphicTools.sp_Image, 
                         "uMVPMatrix");

      GLES20.glUniformMatrix4fv(mtrxhandle, 1, false, m, 0);

      int mSamplerLoc = GLES20.glGetUniformLocation (riGraphicTools.sp_Image, 
                          "s_texture" );

      GLES20.glUniform1i ( mSamplerLoc, 0);

      GLES20.glDrawElements(GLES20.GL_TRIANGLES, indices.length,
               GLES20.GL_UNSIGNED_SHORT, drawListBuffer);

      GLES20.glDisableVertexAttribArray(mPositionHandle);
      GLES20.glDisableVertexAttribArray(mTexCoordLoc);

1 个答案:

答案 0 :(得分:3)

假设您使用必要的数据填充缓冲区,看起来您拥有所需的大部分内容。在您的代码中有一个调用,其中参数不是您必须具有的目标:

GLES20.glGenTextures(idx, texture, 0);

使用Android中的Java绑定,第一个参数是您要生成的ID数,第二个参数是id数组,第三个参数是存储生成的ID的数组中的起始索引。因此,为了生成一个id,并将其存储为texture[idx],正确的参数是:

GLES20.glGenTextures(1, texture, idx);

然后,对于问题的核心部分,您要查找的呼叫是glBindTexture()。此调用定义了大多数与纹理相关的OpenGL操作使用的特定纹理。您将需要在多个地方进行此呼叫。

  • loadTexture()方法中,GLES20.glTexParameteri()GLUtils.texImage2D()都会对当前绑定的纹理进行操作。所以在这些调用之前,你需要添加这个调用来绑定你的新纹理:

    GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, texture[idx]);
    
  • 在绘制操作之前,您需要进行相同的调用。因此,在调用GLES20.glDrawElements()之前,在渲染方法的某处,使用看起来与上面一样的glBindTexture()调用,并使用您想要使用的纹理的idx值。您可以在此处选择在渲染过程中应用了哪些纹理。

有一些机制允许您同时绑定多个纹理。如果着色器需要从多个纹理中进行采样,这非常有用。你很可能还不需要这个。但是一旦你达到这一点,你将想要阅读“纹理单位”,并查看glActiveTexture()电话。