2015年2月16日月曜日

Chapter 5: Data, Buffers

OpenGL Super Bible 6th Edition, Chapter 5: Data, Buffers のメモ

  • バッファは汎用の GPU メモリ上のただのメモリブロック。特に使い方は決まっていない。
  • 名前という名の識別子(実際のところ数値)で識別する。
  • 使用するには
    void glGenBuffers(
        GLsizei n,
        GLuint * buffers);
    で作成したあと
    void glBindBuffer(
        GLenum target,
        GLuint buffer);
    でバインディングポイント(ターゲットと呼ぶこともある)にアタッチする。バインディングポイントは以下のものがある:
    • GL_ARRAY_BUFFER (5章)
    • GL_ATOMIC_COUNTER_BUFFER (5章)
    • GL_COPY_READ_BUFFER (5章)
    • GL_COPY_WRITE_BUFFER (5章)
    • GL_DISPATCH_INDIRECT_BUFFER (10章)
    • GL_DRAW_INDIRECT_BUFFER (7章)
    • GL_ELEMENT_ARRAY_BUFFER (7章)
    • GL_PIXEL_PACK_BUFFER (9章)
    • GL_PIXEL_UNPACK_BUFFER (13章)
    • GL_QUERY_BUFFER (非解説、OpenGL 4.4 で導入)
    • GL_SHADER_STORAGE_BUFFER (5章)
    • GL_TEXTURE_BUFFER (5章)
    • GL_TRANSFORM_FEEDBACK_BUFFER (7章)
    • GL_UNIFORM_BUFFER (5章)
  • OpenGL ではバッファに種類はない。glBindBuffer() した後でも、そのバッファを違うバインディングポイントにバインドすることもできる。
  • 各バッファのメモリはアタッチしたあと
    void glBufferData(
        GLenum target,
        GLsizeiptr size,
        const GLvoid * data,
        GLenum usage);
    で割り当てる。usage 引数は確保した領域をどう使うつもりか OpenGL に対しヒントを与えるためのもの。data は確保したメモリに書き込むデータで NULL でもよい。
  • void glBufferSubData(
        GLenum target,
        GLintptr offset,
        GLsizeiptr size,
        const GLvoid * data);
    で後からデータを書き込むこともできる。
  • void *glMapBuffer(
        GLenum target,
        GLenum access);
    で GPU メモリをメインメモリにマップし、普通のメモリと同様に書き込むこともできる。
  • バッファを一様な値で塗りつぶすには
    void glClearBufferSubData(
        GLenum target,
        GLenum internalformat,
        GLintptr offset,
        GLsizeiptr size,
        GLenum format,
        GLenum type,
        const void * data);
    を使う。
  • バッファ間でコピーを行うには
    void glCopyBufferSubData(
        GLenum readTarget,
        GLenum writeTarget,
        GLintptr readOffset,
        GLintptr writeOffset,
        GLsizeiptr size);
    を使う。コピー元/先ともバインディングポイントで指定するので同じバインディングポイントにバインドしたバッファ間でコピーはできない。一つのバインディングポイントに同時に複数のバッファをバインドすることはできないため。コピーするための一時的なバインド先として GL_COPY_READ_BUFFER, GL_COPY_WRITE_BUFFER バインディングポイントが使用できる。
  • (復習) vertex array object: P20 より
    a vertex array object (VAO), which is an object that represents the vertex fetch stage of the OpenGL pipeline and is used to supply input to the vertex shader.
  • (復習) vertex attribute: シェーダーへのデータ入出力に使うこういうやつ
    // "offset" and "color" are input vertex attributes
    layout (location = 0) in vec4 offset;
    layout (location = 1) in vec4 color;
  • バッファから頂点属性にデータを渡すには、まず、
    void glVertexAttribPointer(
        GLuint index,
        GLint size,
        GLenum type,
        GLboolean normalized,
        GLsizei stride,
        const GLvoid * pointer);
    でどの頂点属性が、バッファ中のどこのデータを使うかを指定する。index は上の layout(location = x) で指定した値。引数名とは裏腹に pointer はバッファ中の開始オフセット。バッファ中の整数データをその整数型の最大値で割って 0.0f - 1.0f の float/doubleに変換してシェーダーに渡す場合は normalized を GL_TRUE にする。次に
    void glEnableVertexAttribArray(GLuint index);
    で拡張点属性が glVertexAttrib*() で渡されたデータではなく、バッファ中のデータを使うようにする。
  • 二つの頂点属性に対してことなるバッファからデータを渡すには、一つ目のバッファを glBindBuffer() した状態で、glVertexAttribPointer(), glEnableVertexAttribArray() を呼び、次に二つ目のバッファを glBindBuffer() した状態で、glVertexAttribPointer(), glEnableVertexAttribArray() を呼ぶ。
  • 二つの頂点属性(例えば座標と色)が交互に並んだバッファからデータをわたすには、その共通のバッファを glBindBuffer() を呼んだ後、stride と pointer を適切に設定して、glVertexAttribPointer() と glEnableVertexAttribArray() をそれぞれ 2 回呼ぶ。

0 件のコメント:

コメントを投稿