OpenGL C++ 应用glTranslatef、glRotatef后获取顶点新坐标问题
实现路径说明
核心原理
你使用的glTranslatef、glRotatef等API本质是修改当前OpenGL上下文内的4x4模型视图矩阵,顶点经过变换后的坐标 = 原始顶点坐标(齐次坐标格式为(x,y,z,1))乘以该矩阵,再做齐次除法得到最终结果。你可以直接读取OpenGL当前的模型视图矩阵,自行完成顶点坐标计算。
可直接复用的实现方案
步骤1:添加顶点变换辅助函数
先在全局位置添加如下工具函数,用于读取当前模型视图矩阵并完成顶点变换计算:
vector<float> transformVertex(float x, float y, float z) { // 读取当前模型视图矩阵,OpenGL矩阵为列主序存储 float modelViewMat[16]; glGetFloatv(GL_MODELVIEW_MATRIX, modelViewMat); // 矩阵乘顶点计算 float transX = modelViewMat[0] * x + modelViewMat[4] * y + modelViewMat[8] * z + modelViewMat[12]; float transY = modelViewMat[1] * x + modelViewMat[5] * y + modelViewMat[9] * z + modelViewMat[13]; float transZ = modelViewMat[2] * x + modelViewMat[6] * y + modelViewMat[10] * z + modelViewMat[14]; float w = modelViewMat[3] * x + modelViewMat[7] * y + modelViewMat[11] * z + modelViewMat[15]; // 齐次坐标归一化 transX /= w; transY /= w; transZ /= w; return {transX, transY, transZ}; }
步骤2:在对应变换位置获取坐标
你需要获取哪个面的变换后坐标,就在对应面的glPushMatrix执行完平移、旋转变换后,遍历原始顶点调用上述函数即可拿到结果,示例如下(以FACE1为例):
glPushMatrix(); glTranslatef(0.0,0.0,0.0); glRotatef(90.0, 1.0, 0.0, 0.0); // 新增代码:获取FACE1变换后的所有顶点坐标 vector<vector<float>> face1Transformed; for (auto &originVert : coordinates) { face1Transformed.push_back(transformVertex(originVert[0], originVert[1], originVert[2])); } // 此时face1Transformed中存储的就是FACE1所有顶点变换后的坐标,可直接存入全局变量供后续业务使用 glBegin(GL_LINE_LOOP); glColor3f( 1.0, 1.0, 1.0 ); for (int i = 0; i < 8; ++i) { glVertex3f(coordinates[i][0], coordinates[i][1], coordinates[i][2]); } glEnd(); glPopMatrix();
其他面的坐标获取逻辑和上面完全一致,在对应面的变换操作完成后加这段代码即可。
可选优化方案
如果后续需要迁移到现代OpenGL核心模式,没有固定管线的矩阵API可用,可以自己封装矩阵运算逻辑:自行实现平移、旋转矩阵的生成,以及矩阵乘向量的计算函数,每次调用OpenGL变换API的同时同步更新自己维护的矩阵自行计算顶点坐标,不依赖OpenGL的矩阵读取接口,适配性更强性能也更高。
内容的提问来源于stack exchange,提问作者baezacaljo
相关产品推荐
相关产品推荐

