c++ - OpenGL在屏幕上移动多边形
问题描述
我在屏幕的两侧有 2 个多边形,它们在一个圆圈中旋转。我要做的是让这两个多边形在旋转时沿 x 轴移动,因此最终它们会在中间重叠,但我不知道该怎么做。
glm::mat4 model_view = glm::scale(glm::mat4(1.0), glm::vec3(0.2, 0.2, 0.8));
model_view = glm::translate(model_view, glm::vec3(-3.0, 0.0, 0.0));
model_view = glm::rotate(model_view, 5*rotate_value, glm::vec3(0.0f, 0.0, 1.0f));
glUniformMatrix4fv(location, 1, GL_FALSE, &model_view[0][0]);
glDrawArrays(GL_POLYGON, 0, NumVertices);
//Object 2
glm::mat4 model_view2 = glm::scale(glm::mat4(1.0), glm::vec3(0.2, 0.2, 0.8));
model_view2 = glm::translate(model_view2, glm::vec3(2.0, 0.0, 0.0));
model_view2 = glm::rotate(model_view2, 5 * rotate_value, glm::vec3(0.0, 0.0, -1.0f));
glUniformMatrix4fv(location, 1, GL_FALSE, &model_view2[0][0]);
//Starting the pipeline
glDrawArrays(GL_POLYGON, 0, NumVertices);
解决方案
我想要做的是让这两个多边形在旋转时沿 x 轴移动,因此最终它们会在中间重叠,但我不知道该怎么做。
为此,您必须根据时间计算旋转和平移。旋转角度和平移矢量是时间的函数。
为此,您必须知道自动画开始以来经过的时间段,在渲染场景的每个时间点。
计算经过时间的一种可能性是使用std::chrono::high_resolution_clock
. 在动画开始时存储当前时间点。计算每一帧中两个时间点的差值,得到过去的时间段。
例如,以下代码以秒为单位计算一个时间段作为 type 的值,double
精度为毫秒:
#include <chrono>
std::chrono::high_resolution_clock::time_point start_time =
std::chrono::high_resolution_clock::now();
std::chrono::high_resolution_clock::time_point current_time =
std::chrono::high_resolution_clock::now();
auto delta_time = current_time - start_time;
double time_s =
(double)std::chrono::duration_cast<std::chrono::milliseconds>(delta_time).count() / 1000.0;
要根据时间计算角度,您必须定义每秒的旋转次数。将时间段除以秒数,然后将结果360
分别乘以2*PI
for 弧度:
float rot_per_s = 10.0f; // 10 full rotations per second
float angle_deg = (float)(360.0 * time_s / rot_per_s);
要创建从一个点到另一个点以及返回的均匀运动,必须定义起点和终点以及完整路径的时间段。
有了这些信息,一个时间点的平移向量可以在运动的起点和终点之间进行线性插值:
double motiontime_s = 5.0f; // from start to end and back in 5 seconds
glm::vec3 start_pt1 = .....; // start point of the movement
glm::vec3 end_pt1 = .....; // end point of the movement
double times;
double pos_rel = modf(time_s / motiontime_s, ×);
float w = pos_rel < 0.5 ? (float)pos_rel * 2.0f : (float)(1.0 - pos_rel) * 2.0f;
glm::vec3 trans1 = start_pt1 * (w-1.0f) + end_pt1*w;
使用角度和平移向量,可以计算对象的模型矩阵并绘制场景:
float rot_per_s = 1.0f/5.0f; // 1 full rotations in 5 second
float angle_deg = (float)(360.0 * time_s * rot_per_s);
double motiontime_s = 5.0f; // from start to end and back in 5 seconds
glm::vec3 start_pt1 = .....;
glm::vec3 end_pt1 = .....;
double times;
double pos_rel = modf(time_s / motiontime_s, ×);
float w = pos_rel < 0.5 ? (float)pos_rel * 2.0f : (float)(1.0 - pos_rel) * 2.0f;
glm::vec3 trans1 = start_pt1 * (w-1.0f) + end_pt1*w;
glm::vec3 start_pt2 = glm::vec3( 1.0f, 0.0f, 0.0f );
glm::vec3 end_pt2 = glm::vec3( 0.0f, 0.0f, 0.0f );
glm::vec3 trans2 = start_pt2 * (w-1.0f) + end_pt2*w;
glm::mat4 model1( 1.0f );
model1 = glm::translate( model1, trans1 );
model1 = glm::rotate( model1, glm::radians(angle_deg), glm::vec3(0.0f, 0.0f, 1.0f) );
model1 = glm::scale( model1, glm::vec3(....) );
glm::mat4 model2( 1.0f );
model2 = glm::translate( model2, trans2 );
model2 = glm::rotate( model2, glm::radians(-angle_deg), glm::vec3(0.0f, 0.0f, 1.0f) );
model2 = glm::scale( model2, glm::vec3(....) );
// Object 1
glUniformMatrix4fv(location, 1, GL_FALSE, glm::value_ptr(model1));
glDrawArrays(GL_POLYGON, 0, NumVertices);
// Object 2
glUniformMatrix4fv(location, 1, GL_FALSE, glm::value_ptr(model2));
glDrawArrays(GL_POLYGON, 0, NumVertices);
结果可能如下所示:
推荐阅读
- java - 在线程“main”java.util.NoSuchElementException中获取错误异常
- ansible - 从 ansible ini 文件生成主机列表
- java - 如何通过单击确定在alertDialog中进行然后转到下一页?
- flutter - 如何使 StreamBuilder 滚动在 Flutter 的 ListView 内工作?
- sql-server - 如何在 ssis 中跳过动态标题行
- node.js - 具有匹配模式的 ioredis 键
- c# - Linq:如何在查询语法中写 Any?
- c - 使用 gzFile 读取数据时文件描述符的偏移量不移动
- c++ - C++ 错误修复:夏威夷语发音程序
- python - 如何为单输入和多输出训练回归模型?