如何在OpenGL中为对象设置固定缩放比例(C++&GLM)
固定对象缩放比例的实现方案(基于GLM)
核心思路
不要直接修改顶点数据来实现缩放,而是利用**模型矩阵(Model Matrix)**在GPU端完成变换。这种方式不仅效率更高,还能保持原始顶点数据的纯净,方便后续封装为类管理对象属性。
步骤1:修改顶点着色器
添加model矩阵uniform,将其与投影矩阵结合,完成顶点的最终变换:
#version 330 core layout(location = 0) in vec3 aPos; uniform mat4 projection; uniform mat4 model; // 新增模型矩阵 void main() { gl_Position = projection * model * vec4(aPos.x, aPos.y, aPos.z, 1.0); }
步骤2:在CPU端用GLM构建模型矩阵
在渲染循环中,基于GLM创建包含固定缩放和位移的模型矩阵,避免直接修改顶点数组:
- 定义固定缩放因子(比如让对象保持0.5倍原始大小)
- 构建模型矩阵:先平移到目标位置,再应用固定缩放
- 将模型矩阵传入着色器
修改后的main函数关键部分:
// 新增固定缩放变量 float scale = 0.5f; while (!glfwWindowShouldClose(window)) { // ... 其他窗口/ImGui初始化代码 ... glClear(GL_COLOR_BUFFER_BIT); glUseProgram(shaderProgram); GLint wsize = glGetUniformLocation(shaderProgram, "wsize"); glUniform2f(wsize, width, height); // 1. 构建模型矩阵:平移 + 固定缩放 glm::mat4 model = glm::mat4(1.0f); model = glm::translate(model, glm::vec3(x, y, z)); // 应用位移 model = glm::scale(model, glm::vec3(scale, scale, 1.0f)); // 固定缩放 // 2. 将模型矩阵传入着色器 GLint modelLoc = glGetUniformLocation(shaderProgram, "model"); glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(model)); // 3. 传入投影矩阵并绘制 glUniformMatrix4fv(glGetUniformLocation(shaderProgram, "projection"), 1, GL_FALSE, glm::value_ptr(projection)); glBindVertexArray(VAO); glDrawArrays(GL_TRIANGLES, 0, 6); // ... ImGui渲染及窗口交换代码 ... }
步骤3:封装为GameObject类
将位置、缩放、模型矩阵计算逻辑封装到类中,便于管理多个对象:
#include <glm/glm.hpp> #include <glm/gtc/matrix_transform.hpp> class GameObject { private: glm::vec3 m_position{0.0f}; glm::vec3 m_scale{1.0f}; // 默认缩放为1倍 public: // 设置位置 void setPosition(const glm::vec3& pos) { m_position = pos; } // 设置固定缩放 void setScale(const glm::vec3& scale) { m_scale = scale; } // 获取计算后的模型矩阵 glm::mat4 getModelMatrix() const { glm::mat4 model = glm::mat4(1.0f); model = glm::translate(model, m_position); model = glm::scale(model, m_scale); return model; } };
使用示例:
// 创建游戏对象 GameObject square; square.setPosition(glm::vec3(x, y, z)); square.setScale(glm::vec3(0.5f, 0.5f, 1.0f)); // 固定缩放 // 渲染时获取矩阵 glm::mat4 model = square.getModelMatrix(); glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(model));
关键注意事项
- 移除原有代码中直接修改顶点数组的逻辑(那部分会导致顶点数据被持续修改,位置偏移越来越大)
- 固定缩放因子可以根据需求调整,比如设为
vec3(0.3f, 0.3f, 1.0f)让对象更小 - 如果需要保持对象在窗口拉伸时视觉大小不变,可以根据窗口宽高比动态调整缩放因子,但这属于动态适配,不符合你当前的固定缩放需求
内容的提问来源于stack exchange,提问作者kai
相关产品推荐
相关产品推荐

