使用索引绘制立方体时如何添加vec2 UV坐标实现纹理映射
索引绘制立方体添加UV纹理坐标的实现方法
1. 核心注意事项
- 立方体的同一空间坐标顶点,在不同面上的UV坐标通常不同,因此原有的顶点复用逻辑仅在使用环境贴图等特殊纹理时可用,普通2D纹理贴立方体需要拆分顶点:只有
位置+法线+UV三者完全一致的顶点才可复用为同一个索引条目。 - 若使用普通2D纹理贴立方体6面,需要将原8个空间顶点拆分为24个顶点(每个面4个独立顶点),索引数组也对应调整为每个面2个三角形的索引。
2. 修改顶点数据结构
你现有每个顶点的属性为vec3位置 + vec3法线,需要新增vec2 UV属性,调整后的单顶点总大小为 3*sizeof(float) + 3*sizeof(float) + 2*sizeof(float) = 32字节。
示例顶点数组修改:
// 每个顶点结构:位置vec3、法线vec3、UV vec2 float vertexArray[] = { // 位置 // 法线 // UV -0.5f, -0.5f, -0.5f, -0.408248f, -0.816497f, -0.408248f, 0.0f, 0.0f, 0.5f, -0.5f, -0.5f, 0.666667f, -0.333333f, -0.666667f, 1.0f, 0.0f, // 剩余顶点按你需要的纹理映射规则补充UV坐标,按面分配UV即可避免纹理拉伸 }; // 向量存储也对应调整为float类型即可,或自定义顶点结构体存储 std::vector<float> vertexArrayVector; vertexArrayVector.insert(vertexArrayVector.begin(), std::begin(vertexArray), std::end(vertexArray));
3. 修改VAO/VBO配置代码
需要调整缓冲大小、步长,新增UV属性的解析规则:
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, indicesVector.size() * sizeof(unsigned int), &indicesVector[0], GL_STATIC_DRAW); glBindBuffer(GL_ARRAY_BUFFER, vertexBufferObject); // 缓冲大小按新的顶点总大小计算 glBufferData(GL_ARRAY_BUFFER, vertexArrayVector.size() * sizeof(float), &vertexArrayVector[0], GL_STATIC_DRAW); // 位置属性 glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8*sizeof(float), (void*)0); glEnableVertexAttribArray(0); // 法线属性(偏移修改为3个float的长度,步长修改为总顶点大小) glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8*sizeof(float), (void*)(3*sizeof(float))); glEnableVertexAttribArray(1); // 新增UV属性 glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8*sizeof(float), (void*)(6*sizeof(float))); glEnableVertexAttribArray(2);
4. 着色器同步修改
顶点着色器中新增layout (location = 2) in vec2 aTexCoord;输入,将UV插值后传递给片元着色器采样纹理即可。
内容的提问来源于stack exchange,提问作者Fabrizo
相关产品推荐
相关产品推荐

