OpenGL图元平移问题:多方块沿XY轴指定距离移动失败
问题
我想要将多个方块沿不同方向移动指定距离。最初我使用glTranslatef(0.4f, 0.4f, 0.0f);(其中0.4f为方块的边长),但更换机器后该方法似乎失效了。我也尝试过使用glVertex3f(-0.4f, 0.4f, 0.0f);,但同样没有效果。
我的顶点初始化代码如下:
float vertices[] = { -0.2f, -0.2f, 0.0f, -0.2f, 0.2f, 0.0f, 0.2f, 0.2f, 0.0f, 0.2f, -0.2f, 0.0f, };
我在main()中初始化缓冲区的代码:
unsigned int VBO; glGenBuffers(1, &VBO); glBindBuffer(GL_ARRAY_BUFFER, VBO); glEnableVertexAttribArray(0); glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void*)0); glEnableVertexAttribArray(0); // Colors unsigned int VBO2; glGenBuffers(1, &VBO2); glBindBuffer(GL_ARRAY_BUFFER, VBO2); glBufferData(GL_ARRAY_BUFFER, sizeof(colors), colors, GL_STATIC_DRAW); glBindBuffer(GL_ARRAY_BUFFER, VBO2); glEnableVertexAttribArray(1); glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, (void*)0);
绘制图形的代码如下:
glDrawArrays(GL_POLYGON, 0, 4); glTranslatef(0.4f, 0.4f, 0.0f); glDrawArrays(GL_POLYGON, 1, 4); glTranslatef(-0.4f, -0.4f, 0.0f);
请问如何实现这些图元分别沿X轴和Y轴移动?
解决方案
问题根源
glTranslatef失效:新机器可能使用了现代OpenGL(3.2+核心模式),glTranslatef属于旧版固定管线函数,核心模式已移除矩阵堆栈相关API,直接调用无效果。- 绘制索引错误:第二个
glDrawArrays起始索引设为1,但顶点数组仅4个顶点,从1取4个会越界,导致绘制异常。 glVertex3f无效:已使用VBO存储顶点数据,现代管线中glVertex3f无法直接生效,必须通过顶点属性数组传递数据。
实现方法
方法1:着色器矩阵变换(推荐,符合现代OpenGL规范)
- 编写顶点着色器,添加模型矩阵uniform变量实现变换:
#version 330 core layout (location = 0) in vec3 aPos; layout (location = 1) in vec3 aColor; out vec3 ourColor; uniform mat4 model; void main() { gl_Position = model * vec4(aPos, 1.0); ourColor = aColor; }
- 绘制时传递不同模型矩阵:
// 绘制第一个方块(无变换) glm::mat4 model = glm::mat4(1.0f); unsigned int modelLoc = glGetUniformLocation(shaderProgram, "model"); glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(model)); glDrawArrays(GL_POLYGON, 0, 4); // 绘制第二个方块(沿X、Y轴各移0.4f) model = glm::translate(model, glm::vec3(0.4f, 0.4f, 0.0f)); glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(model)); glDrawArrays(GL_POLYGON, 0, 4); // 起始索引改为0,避免越界
注:可使用GLM库简化矩阵运算,也可手动构造平移矩阵。
方法2:独立顶点数据(适合简单场景)
直接为每个方块定义偏移后的顶点数据:
float vertices[] = { // 第一个方块(原位置) -0.2f, -0.2f, 0.0f, -0.2f, 0.2f, 0.0f, 0.2f, 0.2f, 0.0f, 0.2f, -0.2f, 0.0f, // 第二个方块(偏移0.4f,0.4f) 0.2f, 0.2f, 0.0f, 0.2f, 0.6f, 0.0f, 0.6f, 0.6f, 0.0f, 0.6f, 0.2f, 0.0f, }; // 绘制两个方块 glDrawArrays(GL_POLYGON, 0, 4); glDrawArrays(GL_POLYGON, 4, 4);
额外注意事项
- 若使用核心模式OpenGL,必须通过着色器+uniform矩阵实现变换,固定管线函数不可用。
- 检查着色器程序是否正确链接,uniform变量位置是否获取正确。
- 确保
glDrawArrays的起始索引和顶点数量不超出数组范围。
内容的提问来源于stack exchange,提问作者Hyziu
相关产品推荐
相关产品推荐

