Android上的VBO:在纹理坐标缓冲区中指出正确的图像

时间:2011-02-09 21:55:05

标签: android opengl-es

有谁知道如何指出存储在HW缓冲区中的纹理缓冲区数组的给定部分?我画了一个三角形条,并用方形图像填充它。在我的纹理中,我有两个彼此相邻的方形图像,因此纹理坐标缓冲区指出它们总共有16个浮点数。

使用软件缓冲区我这样做是为了访问纹理中的第二个图像:

textureCoordinateBuffer.position(8);
gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, textureCoordinateBuffer);

使用硬件缓冲区我假设我做了类似的事情:

// setup HW buffers
// ...
// select HW buffers
gl11.glBindBuffer(GL11.GL_ARRAY_BUFFER,vertexCoordinateBufferIndex);
gl11.glVertexPointer(3, GL10.GL_FLOAT, 0, 0);
gl11.glBindBuffer(GL11.GL_ARRAY_BUFFER, textureCoordinateBufferIndex);

// Point out the first image in the texture coordinate buffer
gl11.glTexCoordPointer(2, GL11.GL_FLOAT, 0, 0);
// Draw
// ...

如果要指出纹理中的第一个图像,哪个效果很好。 但是我想访问第二张图片 - 所以我假设我在最后一行中这样做了:

// Point out the second image in the texture coordinate buffer - doesn't work!
gl11.glTexCoordPointer(2, GL11.GL_FLOAT, 0, 8);

但是这会使图像变得松弛和变色。

任何知道如何正确使用此功能的人?

1 个答案:

答案 0 :(得分:3)

您可能想看看NeHe Android教程。他们详细介绍了这一点并向您展示了您需要做的事情。

具体来说,您正在寻找的课程如下: http://insanitydesign.com/wp/projects/nehe-android-ports/

第6课

您可能没有绑定并启用缓冲区,这是教程中的一个片段:

public void draw(GL10 gl) {
        //Bind our only previously generated texture in this case
        gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]);

        //Point to our buffers
        gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
        gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);

        //Set the face rotation
        gl.glFrontFace(GL10.GL_CCW);

        //Enable the vertex and texture state
        gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer);
        gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, textureBuffer);

        //Draw the vertices as triangles, based on the Index Buffer information
        gl.glDrawElements(GL10.GL_TRIANGLES, indices.length, GL10.GL_UNSIGNED_BYTE, indexBuffer);

        //Disable the client state before leaving
        gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
        gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
    }

信用:疯狂设计 - http://insanitydesign.com/

编辑: 我明白你在问什么。这里有更多应该能够帮助您的代码。如果您查看Android的SpriteMethodTest应用程序: http://apps-for-android.googlecode.com/svn/trunk/SpriteMethodTest

你会注意到Chris Pruett(这个应用程序的开发者)向您展示了向屏幕绘制纹理的多种方法。以下是您正在寻找的代码(我相信)。

Grid.java

public void beginDrawingStrips(GL10 gl, boolean useTexture) {
        beginDrawing(gl, useTexture);
        if (!mUseHardwareBuffers) {
            gl.glVertexPointer(3, mCoordinateType, 0, mVertexBuffer);

            if (useTexture) {
                gl.glTexCoordPointer(2, mCoordinateType, 0, mTexCoordBuffer);
            } 

        } else {
            GL11 gl11 = (GL11)gl;
            // draw using hardware buffers
            gl11.glBindBuffer(GL11.GL_ARRAY_BUFFER, mVertBufferIndex);
            gl11.glVertexPointer(3, mCoordinateType, 0, 0);

            gl11.glBindBuffer(GL11.GL_ARRAY_BUFFER, mTextureCoordBufferIndex);
            gl11.glTexCoordPointer(2, mCoordinateType, 0, 0);

            gl11.glBindBuffer(GL11.GL_ELEMENT_ARRAY_BUFFER, mIndexBufferIndex);
        }
    }

    // Assumes beginDrawingStrips() has been called before this.
    public void drawStrip(GL10 gl, boolean useTexture, int startIndex, int indexCount) {
        int count = indexCount;
        if (startIndex + indexCount >= mIndexCount) {
                count = mIndexCount - startIndex;
        }
        if (!mUseHardwareBuffers) {
            gl.glDrawElements(GL10.GL_TRIANGLES, count,
                    GL10.GL_UNSIGNED_SHORT, mIndexBuffer.position(startIndex));
        } else {
                GL11 gl11 = (GL11)gl;
            gl11.glDrawElements(GL11.GL_TRIANGLES, count,
                    GL11.GL_UNSIGNED_SHORT, startIndex * CHAR_SIZE);

        }
    }

具体来说,您需要查看代码所在的代码!mUseHardwareBuffers的错误分支。我建议您查看完整的Grid.java文件,以便更好地表示如何执行此操作,因为他还设置了纹理指针并使OpenGL能够开始绘制。

旁边注意:我建议从克里斯那里读到这个: http://www.scribd.com/doc/16917369/Writing-Real-Time-Games-for-Android

他进入了这个应用程序的功能,以及他发现最有效的绘制纹理的方法是。