Opengl Es 2.0 - 显示多个纹理

时间:2014-07-04 20:33:02

标签: android opengl-es

所以我能够一次显示1个纹理,但是显示更多纹理时遇到问题。分别为每个纹理调用渲染函数(tex_nr),不确定这是否是一个好方法。这是渲染代码:

private void Render(float[] m, int tex_nr) {

        // Set our shaderprogram to image shader
        GLES20.glUseProgram(riGraphicTools.sp_Image);

        // clear Screen and Depth Buffer, we have set the clear color as black.
        GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT);

        // get handle to vertex shader's vPosition member
        int mPositionHandle = GLES20.glGetAttribLocation(riGraphicTools.sp_SolidColor, "vPosition");

        // Enable generic vertex attribute array
        GLES20.glEnableVertexAttribArray(mPositionHandle);

        // Prepare the triangle coordinate data
        GLES20.glVertexAttribPointer(mPositionHandle, 3,
                                     GLES20.GL_FLOAT, false,
                                     0, vertexBuffer);

     // Get handle to texture coordinates location
        int mTexCoordLoc = GLES20.glGetAttribLocation(riGraphicTools.sp_Image,
                             "a_texCoord" );

        // Enable generic vertex attribute array
        GLES20.glEnableVertexAttribArray ( mTexCoordLoc );

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

        // Get handle to shape's transformation matrix
        int mtrxhandle = GLES20.glGetUniformLocation(riGraphicTools.sp_Image,
                           "uMVPMatrix");

        // Apply the projection and view transformation
        GLES20.glUniformMatrix4fv(mtrxhandle, 1, false, m, 0);

        // Get handle to textures locations
        int mSamplerLoc = GLES20.glGetUniformLocation (riGraphicTools.sp_Image,
                            "s_texture" );

        // Set the sampler texture unit to where we have saved the texture.
        GLES20.glUniform1i ( mSamplerLoc, tex_nr);

        // Draw the triangle
        GLES20.glDrawElements(GLES20.GL_TRIANGLES, indices.length,
                 GLES20.GL_UNSIGNED_SHORT, drawListBuffer);

        // Disable vertex array
        GLES20.glDisableVertexAttribArray(mPositionHandle);
        GLES20.glDisableVertexAttribArray(mTexCoordLoc);

    }

这里加载纹理代码:

texturenames = new int[GameObject.spritePaths.size()];
        GLES20.glGenTextures(GameObject.spritePaths.size(), texturenames, 0);
        for(int i = 0; i < GameObject.spritePaths.size(); i++)
        {
            // Retrieve our image from resources.
            int id = mContext.getResources().getIdentifier(GameObject.spritePaths.get(i), null, mContext.getPackageName());

            // Temporary create a bitmap
            Bitmap bmp = BitmapFactory.decodeResource(mContext.getResources(), id);

            // Bind texture to texturename
            GLES20.glActiveTexture(GLES20.GL_TEXTURE0+i);
            GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, texturenames[i]);

            // 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 the bitmap into the bound texture.
            GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bmp, 0);

            // We are done using the bitmap so we should recycle it.
            bmp.recycle();
        }

作为此代码的结果,仅显示最后加载的纹理,我不知道为什么前者没有显示。我会非常感谢任何线索! 编辑: 实际上,我刚刚发现我可以显示我加载的所有纹理,但一次只能显示1个。所以我猜这个问题与加载无关?看起来每次连续的Render调用(我的函数)都阻止了前一次调用中的绘图...

1 个答案:

答案 0 :(得分:1)

您可以使用glClear()方法拨打Render()

// clear Screen and Depth Buffer, we have set the clear color as black.
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT);

这几乎就是名称所暗示的内容,以及您在评论中捕获的内容:它清除了迄今为止所做的所有渲染。因此,如果多次调用Render()方法,则只显示上次调用的呈现。

如果要为同一帧多次调用Render(),则需要将其从Render()中取出,并在渲染帧开始时仅调用一次。

您的代码中的另一件事看起来有点可疑:

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

除非sp_SolidColorsp_Image具有相同的值,否则您需要从两个不同的着色器程序中查询属性位置。由于sp_Image是您正在使用的程序,因此您应将其作为这两个调用的第一个参数传递。