天天看點

openGL API glVertexAttribPointer詳解

openGL API glVertexAttribPointer詳解

文章目錄

  • ​​openGL API glVertexAttribPointer詳解​​
  • ​​一、官方文檔​​
  • ​​二、翻譯​​
  • ​​例子​​
  • ​​運作結果​​
  • ​​代碼下載下傳​​

一、官方文檔

​​官方說明​​​ Name

glVertexAttribPointer — define an array of generic vertex attribute data

C Specification

void glVertexAttribPointer( GLuint index,

GLint size,

GLenum type,

GLboolean normalized,

GLsizei stride,

const void * pointer);

void glVertexAttribIPointer( GLuint index,

GLint size,

GLenum type,

GLsizei stride,

const void * pointer);

void glVertexAttribLPointer( GLuint index,

GLint size,

GLenum type,

GLsizei stride,

const void * pointer);

Parameters

index

Specifies the index of the generic vertex attribute to be modified.

size

Specifies the number of components per generic vertex attribute. Must be 1, 2, 3, 4. Additionally, the symbolic constant GL_BGRA is accepted by glVertexAttribPointer. The initial value is 4.

type

Specifies the data type of each component in the array. The symbolic constants GL_BYTE, GL_UNSIGNED_BYTE, GL_SHORT, GL_UNSIGNED_SHORT, GL_INT, and GL_UNSIGNED_INT are accepted by glVertexAttribPointer and glVertexAttribIPointer. Additionally GL_HALF_FLOAT, GL_FLOAT, GL_DOUBLE, GL_FIXED, GL_INT_2_10_10_10_REV, GL_UNSIGNED_INT_2_10_10_10_REV and GL_UNSIGNED_INT_10F_11F_11F_REV are accepted by glVertexAttribPointer. GL_DOUBLE is also accepted by glVertexAttribLPointer and is the only token accepted by the type parameter for that function. The initial value is GL_FLOAT.

normalized

For glVertexAttribPointer, specifies whether fixed-point data values should be normalized (GL_TRUE) or converted directly as fixed-point values (GL_FALSE) when they are accessed.

stride

Specifies the byte offset between consecutive generic vertex attributes. If stride is 0, the generic vertex attributes are understood to be tightly packed in the array. The initial value is 0.

pointer

Specifies a offset of the first component of the first generic vertex attribute in the array in the data store of the buffer currently bound to the GL_ARRAY_BUFFER target. The initial value is 0.

Description

glVertexAttribPointer, glVertexAttribIPointer and glVertexAttribLPointer specify the location and data format of the array of generic vertex attributes at index index to use when rendering. size specifies the number of components per attribute and must be 1, 2, 3, 4, or GL_BGRA. type specifies the data type of each component, and stride specifies the byte stride from one attribute to the next, allowing vertices and attributes to be packed into a single array or stored in separate arrays.

For glVertexAttribPointer, if normalized is set to GL_TRUE, it indicates that values stored in an integer format are to be mapped to the range [-1,1] (for signed values) or [0,1] (for unsigned values) when they are accessed and converted to floating point. Otherwise, values will be converted to floats directly without normalization.

For glVertexAttribIPointer, only the integer types GL_BYTE, GL_UNSIGNED_BYTE, GL_SHORT, GL_UNSIGNED_SHORT, GL_INT, GL_UNSIGNED_INT are accepted. Values are always left as integer values.

glVertexAttribLPointer specifies state for a generic vertex attribute array associated with a shader attribute variable declared with 64-bit double precision components. type must be GL_DOUBLE. index, size, and stride behave as described for glVertexAttribPointer and glVertexAttribIPointer.

If pointer is not NULL, a non-zero named buffer object must be bound to the GL_ARRAY_BUFFER target (see glBindBuffer), otherwise an error is generated. pointer is treated as a byte offset into the buffer object’s data store. The buffer object binding (GL_ARRAY_BUFFER_BINDING) is saved as generic vertex attribute array state (GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING) for index index.

When a generic vertex attribute array is specified, size, type, normalized, stride, and pointer are saved as vertex array state, in addition to the current vertex array buffer object binding.

To enable and disable a generic vertex attribute array, call glEnableVertexAttribArray and glDisableVertexAttribArray with index. If enabled, the generic vertex attribute array is used when glDrawArrays, glMultiDrawArrays, glDrawElements, glMultiDrawElements, or glDrawRangeElements is called.

Notes

Each generic vertex attribute array is initially disabled and isn’t accessed when glDrawElements, glDrawRangeElements, glDrawArrays, glMultiDrawArrays, or glMultiDrawElements is called.

GL_UNSIGNED_INT_10F_11F_11F_REV is accepted for type only if the GL version is 4.4 or higher.

Errors

GL_INVALID_VALUE is generated if index is greater than or equal to GL_MAX_VERTEX_ATTRIBS.

GL_INVALID_VALUE is generated if size is not 1, 2, 3, 4 or (for glVertexAttribPointer), GL_BGRA.

GL_INVALID_ENUM is generated if type is not an accepted value.

GL_INVALID_VALUE is generated if stride is negative.

GL_INVALID_OPERATION is generated if size is GL_BGRA and type is not GL_UNSIGNED_BYTE, GL_INT_2_10_10_10_REV or GL_UNSIGNED_INT_2_10_10_10_REV.

GL_INVALID_OPERATION is generated if type is GL_INT_2_10_10_10_REV or GL_UNSIGNED_INT_2_10_10_10_REV and size is not 4 or GL_BGRA.

GL_INVALID_OPERATION is generated if type is GL_UNSIGNED_INT_10F_11F_11F_REV and size is not 3.

GL_INVALID_OPERATION is generated by glVertexAttribPointer if size is GL_BGRA and normalized is GL_FALSE.

GL_INVALID_OPERATION is generated if zero is bound to the GL_ARRAY_BUFFER buffer object binding point and the pointer argument is not NULL.

Associated Gets

glGet with argument GL_MAX_VERTEX_ATTRIBS

glGetVertexAttrib with arguments index and GL_VERTEX_ATTRIB_ARRAY_ENABLED

glGetVertexAttrib with arguments index and GL_VERTEX_ATTRIB_ARRAY_SIZE

glGetVertexAttrib with arguments index and GL_VERTEX_ATTRIB_ARRAY_TYPE

glGetVertexAttrib with arguments index and GL_VERTEX_ATTRIB_ARRAY_NORMALIZED

glGetVertexAttrib with arguments index and GL_VERTEX_ATTRIB_ARRAY_STRIDE

glGetVertexAttrib with arguments index and GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING

glGet with argument GL_ARRAY_BUFFER_BINDING

glGetVertexAttribPointerv with arguments index and GL_VERTEX_ATTRIB_ARRAY_POINTER

Version Support

OpenGL Version

Function / Feature Name 2.0 2.1 3.0 3.1 3.2 3.3 4.0 4.1 4.2 4.3 4.4 4.5

glVertexAttribIPointer - - ✔ ✔ ✔ ✔ ✔ ✔ ✔ ✔ ✔ ✔

glVertexAttribLPointer - - - - - - - ✔ ✔ ✔ ✔ ✔

glVertexAttribPointer ✔ ✔ ✔ ✔ ✔ ✔ ✔ ✔ ✔ ✔ ✔ ✔

See Also

glBindAttribLocation, glBindBuffer, glDisableVertexAttribArray, glDrawArrays, glDrawElements, glDrawRangeElements, glEnableVertexAttribArray, glMultiDrawArrays, glMultiDrawElements, glVertexAttrib

Copyright

Copyright © 2003-2005 3Dlabs Inc. Ltd. Copyright © 2010-2014 Khronos Group. This material may be distributed subject to the terms and conditions set forth in the Open Publication License, v 1.0, 8 June 1999. http://opencontent.org/openpub/.

二、翻譯

Name

glVertexAttribPointer — 定義頂點屬性數組

C Specification

void glVertexAttribPointer( GLuint index,

GLint size,

GLenum type,

GLboolean normalized,

GLsizei stride,

const GLvoid * pointer);

Parameters

index

指定要修改的頂點屬性的索引值

size

指定每個頂點屬性的元件數量。必須為1、2、3或者4。初始值為4。(夢維:如position是由3個(x,y,z)組成,而顔色是4個(r,g,b,a))

type

指定數組中每個元件的資料類型。可用的符号常量有GL_BYTE, GL_UNSIGNED_BYTE, GL_SHORT,GL_UNSIGNED_SHORT, GL_FIXED, 和 GL_FLOAT,初始值為GL_FLOAT。

normalized

指定當被通路時,固定點資料值是否應該被歸一化(GL_TRUE)或者直接轉換為固定點值(GL_FALSE)。

stride

指定連續頂點屬性之間的偏移量。如果為0,那麼頂點屬性會被了解為:它們是緊密排列在一起的。初始值為0。

pointer

指定一個指針,指向數組中第一個頂點屬性的第一個元件。初始值為0。

Description

glVertexAttribPointer 指定了渲染時索引值為 index 的頂點屬性數組的資料格式和位置。size指定每個屬性值的元件數量且必須為1、2、3、4之一。type指定每個元件的資料格式,stride指定了一個屬性到下一個屬性之間的步長(這就允許屬性值被存儲在單一數組或者不同的數組中)。當數組中的值被通路并被轉換至浮點值時,如果normalized被設定為GL_TRUE,意味着整數型的值會被映射至區間​​​-1,1​​,或者區間[0,1](無符号整數),反之,這些值會被直接轉換為浮點值而不進行歸一化處理。

如果一個名稱非零的緩沖對象被綁定至GL_ARRAY_BUFFER目标(見glBindBuffer)且此時一個定點屬性數組被指定了,那麼pointer被當做該緩沖對象資料存儲區的位元組偏移量。并且,緩沖對象綁定(GL_ARRAY_BUFFER_BINDING)會被存為索引為index的頂點屬性數組用戶端狀态(GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING);(Also, the buffer object binding (GL_ARRAY_BUFFER_BINDING) is saved as generic vertex attribute array client-side state (GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING) for index index.)

當一個頂點屬性數組被指定時,除了目前的頂點數組緩沖對象綁定,size, type, normalized, stride, 和 pointer 也會被存為用戶端狀态

要啟用或者禁用頂點屬性數組,調用glEnableVertexAttribArray和glDisableVertexAttribArray傳入參數index。如果啟用,那麼當glDrawArrays或者glDrawElements被調用時,頂點屬性數組會被使用。

Notes

當glDrawArrays或者glDrawElements被調用時,每個頂點屬性數組初始狀态是禁用的,不會被通路。

glVertexAttribPointer一般在用戶端實作。

Errors

GL_INVALID_ENUM錯誤:如果 type 不是可接受的值。

GL_INVALID_VALUE錯誤: 如果 index 大于等于 GL_MAX_VERTEX_ATTRIBS.

GL_INVALID_VALUE錯誤: 如果 size 不是 1, 2, 3, 或 4.

GL_INVALID_VALUE錯誤: 如果 stride 小于零.

Associated Gets

glGet 傳入參數 GL_MAX_VERTEX_ATTRIBS

glGetVertexAttrib 傳入參數 index 和 GL_VERTEX_ATTRIB_ARRAY_ENABLED

glGetVertexAttrib 傳入參數 index 和 GL_VERTEX_ATTRIB_ARRAY_SIZE

glGetVertexAttrib 傳入參數 index 和 GL_VERTEX_ATTRIB_ARRAY_TYPE

glGetVertexAttrib 傳入參數 index 和 GL_VERTEX_ATTRIB_ARRAY_NORMALIZED

glGetVertexAttrib 傳入參數 index 和 GL_VERTEX_ATTRIB_ARRAY_STRIDE

glGetVertexAttrib 傳入參數index 和 GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING

glGet 傳入參數 GL_ARRAY_BUFFER_BINDING

glGetVertexAttribPointerv 傳入參數 index 和 GL_VERTEX_ATTRIB_ARRAY_POINTER

See Also

glBindAttribLocation, glBindBuffer, glDisableVertexAttribArray, glDrawArrays, glDrawElements, glEnableVertexAttribArray,glVertexAttrib

例子

#include "glew/glew.h"
#include "glfw/glfw3.h"
#include "glm/glm.hpp"
#include "glm/gtc/matrix_transform.hpp"   // glm::translate, glm::rotate, glm::scale, glm::perspective
#include "glm/gtc/type_ptr.hpp"           // glm::value_ptr
#include "Utils.h"
#include <iostream>
#include <string>
#include <fstream>

using namespace std;

static const int Screen_Width = 800;
static const int Screen_Height = 600;
static const int NumberVAOs = 1;
static const int NumberVBOs = 2;
int width = 0;
int height = 0;


Utils util = Utils();
float cameraX = 0.f, cameraY = 0.f, cameraZ = 0.f;
float cubeLocX = 0.f, cubeLocY = 0.f, cubeLocZ = 0.f;
GLuint renderingProgram = 0;
GLuint vao[NumberVAOs] = { 0 };
GLuint vbo[NumberVBOs] = { 0 };

// variable allocation for display
GLuint mvLoc = 0, projLoc = 0;
float aspect = 0.f;
glm::mat4 pMat(1), vMat(1), mMat(1), mvMat(1);

void setupVertices(void)
{
  float vertexPositions[108] = {
    -1.0f,  1.0f, -1.0f, -1.0f, -1.0f, -1.0f, 1.0f, -1.0f, -1.0f,
    1.0f, -1.0f, -1.0f, 1.0f,  1.0f, -1.0f, -1.0f,  1.0f, -1.0f,
    1.0f, -1.0f, -1.0f, 1.0f, -1.0f,  1.0f, 1.0f,  1.0f, -1.0f,
    1.0f, -1.0f,  1.0f, 1.0f,  1.0f,  1.0f, 1.0f,  1.0f, -1.0f,
    1.0f, -1.0f,  1.0f, -1.0f, -1.0f,  1.0f, 1.0f,  1.0f,  1.0f,
    -1.0f, -1.0f,  1.0f, -1.0f,  1.0f,  1.0f, 1.0f,  1.0f,  1.0f,
    -1.0f, -1.0f,  1.0f, -1.0f, -1.0f, -1.0f, -1.0f,  1.0f,  1.0f,
    -1.0f, -1.0f, -1.0f, -1.0f,  1.0f, -1.0f, -1.0f,  1.0f,  1.0f,
    -1.0f, -1.0f,  1.0f,  1.0f, -1.0f,  1.0f,  1.0f, -1.0f, -1.0f,
    1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f,  1.0f,
    -1.0f,  1.0f, -1.0f, 1.0f,  1.0f, -1.0f, 1.0f,  1.0f,  1.0f,
    1.0f,  1.0f,  1.0f, -1.0f,  1.0f,  1.0f, -1.0f,  1.0f, -1.0f
  };

  //生成頂點數組對象
  glGenVertexArrays(NumberVAOs, vao);
  glBindVertexArray(vao[0]);

  //生成頂點緩存對象,并傳回緩存對象的辨別符id
  glGenBuffers(NumberVBOs, vbo);
  //綁定/激活緩存對象,target告訴VBO該緩存對象将儲存頂點數組資料還是索引數組資料:GL_ARRAY_BUFFER或GL_ELEMENT_ARRAY
  glBindBuffer(GL_ARRAY_BUFFER, vbo[0]);
  //glBindBuffer(GL_ARRAY_BUFFER, vbo[1]);
  //将頂點資料拷貝到緩存對象中
  glBufferData(GL_ARRAY_BUFFER, sizeof(vertexPositions),  vertexPositions, GL_STATIC_DRAW);    //有問題
  //glDrawArrays(GL_TRIANGLES, 0, 108);
}

void init(GLFWwindow* window)
{
  renderingProgram = Utils::createShaderProgram("vertShader.glsl", "fragShader.glsl");
  cameraX = 0.f;
  cameraY = 0.f;
  cameraZ = 8.f;

  cubeLocX = 0.f;
  cubeLocY = -2.f;
  cubeLocZ = 0.f;

  setupVertices();
}

void display(GLFWwindow* window, double currentTime)
{
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  glClearColor(0.f, 0.5f, 1.f, 1.f);

  glUseProgram(renderingProgram);
  /*Utils::printProgramLog(renderingProgram);*/   //printProgramLog()是私有函數
  //擷取uniform變量在着色器程式中的位置序号,通過該序号可以設定一緻變量的值,如果沒有該變量則傳回-1
  mvLoc = glGetUniformLocation(renderingProgram, "mv_matrix");
  projLoc = glGetUniformLocation(renderingProgram, "proj_matrix");

  //glfwGetFramebufferSize(window, const_cast<int*>(&Screen_Width), const_cast<int*>(&Screen_Height));
  width = 800;
  height = 600;
  glfwGetFramebufferSize(window, &width, &height);
  aspect = (float)(Screen_Width) / (float)(Screen_Height);
  pMat = glm::perspective(glm::radians(60.f), aspect, 0.1f, 1000.f);  //有問題
  //pMat = glm::perspective(1.0472f, aspect, 0.1f, 1000.0f);

  vMat = glm::translate(glm::mat4(1.f), glm::vec3(-cameraX, -cameraY, -cameraZ));
  mMat = glm::translate(glm::mat4(1.f), glm::vec3(cubeLocX, cubeLocY, cubeLocZ));

  mvMat = mMat * vMat;
  //更改一個uniform矩陣變量或數組的值。要更改的uniform變量的位置由location指定,location的值應該由glGetUniformLocation函數傳回
  glUniformMatrix4fv(mvLoc, 1, GL_FALSE, glm::value_ptr(mvMat));
  glUniformMatrix4fv(projLoc, 1, GL_FALSE, glm::value_ptr(pMat));

  glBindBuffer(GL_ARRAY_BUFFER, vbo[0]);
  //glBufferData(GL_ARRAY_BUFFER, sizeof(vbo), vbo, GL_STATIC_DRAW);
  //glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), 0);   //有問題
  //指定了渲染時索引值為 index 的頂點屬性數組的資料格式和位置
  /*Parameters
  index
    指定要修改的頂點屬性的索引值

    size
    指定每個頂點屬性的元件數量。必須為1、2、3或者4。初始值為4。(夢維:如position是由3個(x, y, z)組成,而顔色是4個(r, g, b, a))

    type
    指定數組中每個元件的資料類型。可用的符号常量有GL_BYTE, GL_UNSIGNED_BYTE, GL_SHORT, GL_UNSIGNED_SHORT, GL_FIXED, 和 GL_FLOAT,初始值為GL_FLOAT。

    normalized
    指定當被通路時,固定點資料值是否應該被歸一化(GL_TRUE)或者直接轉換為固定點值(GL_FALSE)。

    stride
    指定連續頂點屬性之間的偏移量。如果為0,那麼頂點屬性會被了解為:它們是緊密排列在一起的。初始值為0。

    pointer
    指定一個指針,指向數組中第一個頂點屬性的第一個元件。初始值為0。
    */
  glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
  glEnableVertexAttribArray(0);

  glEnable(GL_DEPTH_TEST);
  glDepthFunc(GL_LEQUAL);

  glDrawArrays(GL_TRIANGLES, 0, 36);

}


int main(int argc, char** argv)
{
  int glfwStatue = glfwInit();
  if (GLFW_FALSE == glfwStatue)
  {
    cout << "GLFW initialize failed, invoke glfwInit().....Error file:" << __FILE__ << "......Error line:" << __LINE__ << endl;
    glfwTerminate();
    exit(EXIT_FAILURE);
  }
  glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
  glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 6);
  glfwWindowHint(GLFW_OPENGL_CORE_PROFILE, GLFW_OPENGL_PROFILE);

  GLFWwindow* window = glfwCreateWindow(Screen_Width, Screen_Height, "Draw color cube", nullptr, nullptr);
  if (!window)
  {
    cout << "GLFW create window failed, invoke glfwCreateWindow().......Error file:" << __FILE__ << "......Error line:" << __LINE__ << endl;
    glfwTerminate();
    exit(EXIT_FAILURE);
  }

  glfwMakeContextCurrent(window);

  int glewSatue = glewInit();
  if (GLEW_OK != glewSatue)
  {
    cout << "GLEW initialize failed, invoke glewInit().....Error file:" << __FILE__ << "......Error line:" << __LINE__ << endl;
    exit(EXIT_FAILURE);
  }
  //由于這些原因,應用程式通常希望将交換間隔設定為1。可以将其設定為更高的值,但通常不建議這樣做,因為這樣會導緻輸入延遲。
  glfwSwapInterval(1);

  init(window);

  while (!glfwWindowShouldClose(window))
  {
    display(window, glfwGetTime());
    glfwSwapBuffers(window);
    glfwPollEvents();
  }

  glfwDestroyWindow(window);
  glfwTerminate();
  exit(EXIT_SUCCESS);

  return 0;
}      

運作結果

代碼下載下傳