在 OpenGL ES 2.0 中切换到 VBO 时发生崩溃

发布于 2025-01-12 09:38:51 字数 2793 浏览 1 评论 0原文

我使用此代码来渲染单个纹理矩形。我有 2 个浮点用于顶点位置,2 个浮点用于纹理坐标,1 个浮点用于纹理 id。此代码可以正常工作并渲染我的矩形(不要介意奇怪的浮点数据):

public void renderNonVBO(){
    float [] data = new float[]{66.61024f, 27.520004f, 0.0f, 0.206f, 0.0f,
            77.950134f, 49.80019f, 0.141f, 0.206f, 0.0f,
            33.389763f, 72.479996f, 0.0f, 0.206f, 0.0f,
            22.049864f, 50.19981f, 0.0f, 0.206f, 0.0f};

    FloatBuffer b = ByteBuffer.allocateDirect(20 * FLOAT_SIZE).order(ByteOrder.nativeOrder()).asFloatBuffer();
    b.put(data);
    b.position(0);

    GLES20.glEnableVertexAttribArray(aPosition);
    GLES20.glVertexAttribPointer(aPosition, POSITION_SIZE, GLES20.GL_FLOAT, false, TOTAL_SIZE * FLOAT_SIZE, b);

    b.position(2);
    GLES20.glEnableVertexAttribArray(aTexPos);
    GLES20.glVertexAttribPointer(aTexPos, TEXTURE_SIZE, GLES20.GL_FLOAT, false, TOTAL_SIZE * FLOAT_SIZE, b);

    b.position(4);
    GLES20.glEnableVertexAttribArray(aTexIdPos);
    GLES20.glVertexAttribPointer(aTexIdPos, TEXTURE_ID_SIZE, GLES20.GL_FLOAT, false, TOTAL_SIZE * FLOAT_SIZE, b);

    GLES20.glDrawArrays(GLES20.GL_TRIANGLE_FAN, 0, 4);
}

但是当我尝试使用此代码切换到 VBO 时,我的应用程序崩溃:

public void renderVBO(){
    float [] data = new float[]{66.61024f, 27.520004f, 0.0f, 0.206f, 0.0f,
            77.950134f, 49.80019f, 0.141f, 0.206f, 0.0f,
            33.389763f, 72.479996f, 0.0f, 0.206f, 0.0f,
            22.049864f, 50.19981f, 0.0f, 0.206f, 0.0f};

    FloatBuffer b = ByteBuffer.allocateDirect(20 * FLOAT_SIZE).order(ByteOrder.nativeOrder()).asFloatBuffer();
    b.put(data);
    b.position(0);

    GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, buffers[0]);
    GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, b.capacity() * FLOAT_SIZE, b, GLES20.GL_STATIC_DRAW);

    GLES20.glEnableVertexAttribArray(aPosition);
    GLES20.glVertexAttribPointer(aPosition, POSITION_SIZE, GLES20.GL_FLOAT, false, TOTAL_SIZE * FLOAT_SIZE, 0);

    GLES20.glEnableVertexAttribArray(aTexPos);
    GLES20.glVertexAttribPointer(aTexPos, TEXTURE_SIZE, GLES20.GL_FLOAT, false, TOTAL_SIZE * FLOAT_SIZE, 8);

    GLES20.glEnableVertexAttribArray(aTexIdPos);
    GLES20.glVertexAttribPointer(aTexIdPos, TEXTURE_ID_SIZE, GLES20.GL_FLOAT, false, TOTAL_SIZE * FLOAT_SIZE, 16);

    GLES20.glDrawArrays(GLES20.GL_TRIANGLE_FAN, 0, 4);
}

唯一的区别是使用 VBO 和 glVertexAttribPointer 的最后一个参数,现在是数字偏移量而不是 FloatBuffer。 buffer[0] 由 glGenBuffers 返回。当我查看 logcat 时,我看到这条消息:

D/emuglGLESv2_enc: sendVertexAttributes: bad offset / len!!!!!

这很奇怪,因为我的偏移量长度在这里必须正确,它们对于两种方法都是相同的。我的常量:

final int FLOAT_SIZE = 4;
final int POSITION_SIZE = 2;
final int TEXTURE_SIZE = 2;
final int TEXTURE_ID_SIZE = 1;
final int TOTAL_SIZE = POSITION_SIZE + TEXTURE_SIZE + TEXTURE_ID_SIZE;

我做错了什么?

I use this code to render single textured rectangle. I have 2 floats for vertex position, 2 floats for texture coordinates and 1 for texture id.This code works correctly and renders my rectangle (don't mind the weird float data):

public void renderNonVBO(){
    float [] data = new float[]{66.61024f, 27.520004f, 0.0f, 0.206f, 0.0f,
            77.950134f, 49.80019f, 0.141f, 0.206f, 0.0f,
            33.389763f, 72.479996f, 0.0f, 0.206f, 0.0f,
            22.049864f, 50.19981f, 0.0f, 0.206f, 0.0f};

    FloatBuffer b = ByteBuffer.allocateDirect(20 * FLOAT_SIZE).order(ByteOrder.nativeOrder()).asFloatBuffer();
    b.put(data);
    b.position(0);

    GLES20.glEnableVertexAttribArray(aPosition);
    GLES20.glVertexAttribPointer(aPosition, POSITION_SIZE, GLES20.GL_FLOAT, false, TOTAL_SIZE * FLOAT_SIZE, b);

    b.position(2);
    GLES20.glEnableVertexAttribArray(aTexPos);
    GLES20.glVertexAttribPointer(aTexPos, TEXTURE_SIZE, GLES20.GL_FLOAT, false, TOTAL_SIZE * FLOAT_SIZE, b);

    b.position(4);
    GLES20.glEnableVertexAttribArray(aTexIdPos);
    GLES20.glVertexAttribPointer(aTexIdPos, TEXTURE_ID_SIZE, GLES20.GL_FLOAT, false, TOTAL_SIZE * FLOAT_SIZE, b);

    GLES20.glDrawArrays(GLES20.GL_TRIANGLE_FAN, 0, 4);
}

But when I try to switch to VBOs using this code, my app crashes:

public void renderVBO(){
    float [] data = new float[]{66.61024f, 27.520004f, 0.0f, 0.206f, 0.0f,
            77.950134f, 49.80019f, 0.141f, 0.206f, 0.0f,
            33.389763f, 72.479996f, 0.0f, 0.206f, 0.0f,
            22.049864f, 50.19981f, 0.0f, 0.206f, 0.0f};

    FloatBuffer b = ByteBuffer.allocateDirect(20 * FLOAT_SIZE).order(ByteOrder.nativeOrder()).asFloatBuffer();
    b.put(data);
    b.position(0);

    GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, buffers[0]);
    GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, b.capacity() * FLOAT_SIZE, b, GLES20.GL_STATIC_DRAW);

    GLES20.glEnableVertexAttribArray(aPosition);
    GLES20.glVertexAttribPointer(aPosition, POSITION_SIZE, GLES20.GL_FLOAT, false, TOTAL_SIZE * FLOAT_SIZE, 0);

    GLES20.glEnableVertexAttribArray(aTexPos);
    GLES20.glVertexAttribPointer(aTexPos, TEXTURE_SIZE, GLES20.GL_FLOAT, false, TOTAL_SIZE * FLOAT_SIZE, 8);

    GLES20.glEnableVertexAttribArray(aTexIdPos);
    GLES20.glVertexAttribPointer(aTexIdPos, TEXTURE_ID_SIZE, GLES20.GL_FLOAT, false, TOTAL_SIZE * FLOAT_SIZE, 16);

    GLES20.glDrawArrays(GLES20.GL_TRIANGLE_FAN, 0, 4);
}

The only difference is using VBO and last parameter of glVertexAttribPointer, that is now numeric offset instead of FloatBuffer. buffer[0] was returned by glGenBuffers. When I look into logcat I see this message:

D/emuglGLESv2_enc: sendVertexAttributes: bad offset / len!!!!!

Which is weird, because my offsets are lengths must be correct here, they are the same for both methods. My constants:

final int FLOAT_SIZE = 4;
final int POSITION_SIZE = 2;
final int TEXTURE_SIZE = 2;
final int TEXTURE_ID_SIZE = 1;
final int TOTAL_SIZE = POSITION_SIZE + TEXTURE_SIZE + TEXTURE_ID_SIZE;

What am I doing wrong?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文