【问题标题】:What's the "offset" parameter in GLES20.glVertexAttribPointer/glDrawElements, and where does ptr/indices come from?GLES20.glVertexAttribPointer/glDrawElements 中的“offset”参数是什么,ptr/indices 来自哪里?
【发布时间】:2011-10-10 05:07:22
【问题描述】:

我在 Android 中使用 OpenGL ES 2.0,查看the docs for GLES20 发现了以下方法:

public static void glDrawElements(
    int mode, int count, int type, Buffer indices)
public static void glDrawElements(
    int mode, int count, int type, int offset)

public static void glVertexAttribPointer(
    int indx, int size, int type, boolean normalized, int stride, Buffer ptr)
public static void glVertexAttribPointer(
    int indx, int size, int type, boolean normalized, int stride, int offset)

采用Buffer 对象的两种方法对我来说是有意义的,但其他两种则没有。他们从哪里获得索引/属性值(分别),offset 的偏移量是什么? (我假设这两个问题的答案相同。)

【问题讨论】:

  • 这两个奇怪的方法都被标记为“9级”,(我目前正在为8级编码),所以这比什么都更能满足我的好奇心......

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


【解决方案1】:

原型中的偏移意味着您在此调用之前提交了 INDEX 数组。如果您正在使用 VBO(顶点缓冲区对象),则应该使用它。使用 glBindBuffer 绑定索引缓冲区并在需要时指定偏移量下一个电话。

首先,您需要绑定缓冲区(此处为索引缓冲区),您可以指定元素从哪里开始以“偏移量”开头。

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, g_resources.element_buffer);
glDrawElements(
    GL_TRIANGLE_STRIP,  /* mode */
    4,                  /* count */
    GL_UNSIGNED_SHORT,  /* type */
    (void*)0            /* element array buffer offset */
);

 public static void glVertexAttribPointer(
int indx, int size, int type, boolean normalized, int stride, int offset)

这意味着您在此调用之前提交了顶点缓冲区,并且您可以指定它应该在缓冲区中使用的偏移量。 请查看以下链接以获取更多帮助。 http://duriansoftware.com/joe/An-intro-to-modern-OpenGL.-Chapter-2.3:-Rendering.html

正如您所料,两者的原因相同:)。希望这会有所帮助!

更新:你需要创建一个缓冲区来绑定它。这可以通过以下步骤来完成。

     glGenBuffers(); // create a buffer object
     glBindBuffer(); // use the buffer
     glBufferData(); // allocate memory in the buffer

查看此链接以创建 VBO。 http://www.opengl.org/wiki/Vertex_Buffer_Object

关于Offset类型:offset作为指针传递,但参数用于其整数值,所以我们将整数强制转换为void*。

【讨论】:

  • 谢谢,但是当您在上面似乎使用 NULL 时,非零“偏移量”会变成什么?此外, GLES.glBindBuffer 只需要几个整数。 n 个索引/属性值在哪里传递?我对VBO一无所知……我想我还有一些阅读要做。
  • @LaurenceGonsalves:为您的问题添加了更新。如果对此有任何疑问,请告诉我。
  • 谢谢。这样就搞清楚了。我的部分困惑似乎也来自于我正在查看 glDrawElements 的 OpenGL(非 ES)文档,并且没有看到任何提到奇怪的指针双重用途的事实。 (顺便说一句:Ick!他们为什么这样做?OpenGL 通常不会为不同类型的参数添加额外的函数。)
  • @LaurenceGonsalves:是的!这对我来说也很奇怪!但在某些链接中,这是出于“历史原因”! - 该死!我真的不知道那是什么意思:P
【解决方案2】:

方法

public static void glDrawElements(
    int mode, int count, int type, int offset)

用于使用 VBO 索引进行渲染。

offset - 是 indexVBO 的偏移量以字节为单位;

在使用它之前,您应该将索引上传到 VBO 对象:

import static android.opengl.GLES20.*;

private static final int SIZEOF_SHORT = 2;

void fillIndices() {
    int indexAmount = ...;
    int sizeBytes = indexAmount * SIZEOF_SHORT;
    ShortBuffer indicesS = ByteBuffer.allocateDirect(sizeBytes).order(ByteOrder.nativeOrder()).asShortBuffer();
    indicesS.put(getShortIndices(indexAmount));

    indicesS.position(0);

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexVBO);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeBytes, indicesS, GL_STATIC_DRAW);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
}

short[] getShortIndices(int indexAmount) {
    short[] indices = new short[indexAmount];
    // fill indices here
    return indices;
}

然后你就可以绑定它并与glDrawElements()一起使用

public void draw(){
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexVBO);
    glDrawElements(GL_TRIANGLE_STRIP, indexCount, GL_UNSIGNED_SHORT, firstIndex * SIZEOF_SHORT);}
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
}

您可以使用 GL_UNSIGNED_BYTE、GL_UNSIGNED_SHORT 和 GL_UNSIGNED_INT 作为索引。

【讨论】:

    猜你喜欢
    • 2011-11-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-26
    • 1970-01-01
    • 2021-09-12
    相关资源
    最近更新 更多