使用索引时如何为 UV 添加 vec2 以进行纹理映射
Posted
技术标签:
【中文标题】使用索引时如何为 UV 添加 vec2 以进行纹理映射【英文标题】:How to add vec2 for UV for texture mapping when using indices 【发布时间】:2021-07-31 22:22:48 【问题描述】:我正在尝试将纹理映射应用于我的立方体,但不确定如何进行。目前我正在使用索引来避免重复 vec3s 来制作一个立方体和一个点及其法线的顶点数组,如下所示:
// Cube data as our basic building block
unsigned int indices[] =
10, 8, 0, 2, 10, 0, 12, 10, 2, 4, 12, 2,
14, 12, 4, 6, 14, 4, 8, 14, 6, 0, 8, 6,
12, 14, 8, 10, 12, 8, 2, 0, 6, 4, 2, 6
;
vec3 vertexArray[] =
vec3(-0.5f, -0.5f, -0.5f), vec3(-0.408248, -0.816497, -0.408248),
vec3(0.5f, -0.5f, -0.5f), vec3(0.666667, -0.333333, -0.666667),
vec3(0.5f, 0.5f, -0.5f), vec3(0.408248, 0.816497, -0.408248),
vec3(-0.5f, 0.5f, -0.5f), vec3(-0.666667, 0.333333, -0.666667),
vec3(-0.5f, -0.5f, 0.5f), vec3(-0.666667, -0.333333, 0.666667),
vec3(0.5f, -0.5f, 0.5f), vec3(0.666667, -0.666667, 0.333333),
vec3(0.5f, 0.5f, 0.5f), vec3(0.408248, 0.408248, 0.816497),
vec3(-0.5f, 0.5f, 0.5f), vec3(-0.408248, 0.816497, 0.408248),
;
// convert arrays to vectors
std::vector<vec3> vertexArrayVector;
vertexArrayVector.insert(vertexArrayVector.begin(), std::begin(vertexArray), std::end(vertexArray));
std::vector<unsigned int> indicesVector;
indicesVector.insert(indicesVector.begin(), std::begin(indices), std::end(indices));
我现在想将纹理应用到立方体,但我不确定在使用索引时如何为 UV 添加 vec2 的使用。如果有帮助,我会创建这样的 VBO 和 VAO:
GLuint vertexBufferObject;
GLuint indexBufferObject;
GLuint vertexArrayObject;
glGenVertexArrays(1, &vertexArrayObject);
glGenBuffers(1, &indexBufferObject);
glGenBuffers(1, &vertexBufferObject);
glBindVertexArray(vertexArrayObject);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBufferObject);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(vertexIndicesArray[0]) * vertexIndicesArray.size(), &vertexIndicesArray[0], GL_STATIC_DRAW);
// Upload Vertex Buffer to the GPU, keep a reference to it (vertexBufferObject)
glBindBuffer(GL_ARRAY_BUFFER, vertexBufferObject);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertexPointsArray[0]) * vertexPointsArray.size(), &vertexPointsArray[0], GL_STATIC_DRAW);
// Teach GPU how to read position data from vertexBufferObject
glVertexAttribPointer(0, // attribute 0 matches aPos in Vertex Shader
3, // size
GL_FLOAT, // type
GL_FALSE, // normalized?
0, // 0 stride
(void*)0 // array buffer offset
);
glEnableVertexAttribArray(0);
// Teach GPU how to read normals data from vertexBufferObject
glVertexAttribPointer(1, // attribute 1 matches normals in Vertex Shader
3,
GL_FLOAT,
GL_FALSE,
0,
(void*)sizeof(glm::vec3) // normal is offseted a vec3 (comes after position)
);
glEnableVertexAttribArray(1);
【问题讨论】:
【参考方案1】:具有 5 个分量(x、y、z、u、v)的元组的顶点坐标和纹理坐标。如果您有一个由面共享但与不同纹理坐标相关联的顶点坐标,则需要复制一个顶点坐标。您必须为网格中所需的每个顶点坐标和纹理坐标组合指定 1 个属性元组。 不能为顶点坐标和纹理坐标指定不同的索引。请参阅Rendering meshes with multiple indices 和Why does OpenGL not support multiple index buffering?。
【讨论】:
以上是关于使用索引时如何为 UV 添加 vec2 以进行纹理映射的主要内容,如果未能解决你的问题,请参考以下文章