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;
}

运行结果

在这里插入图片描述

代码下载

源码下载

  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值