首页 > 解决方案 > 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);

标签: c++opengl

解决方案


我想要做的是让这两个多边形在旋转时沿 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*PIfor 弧度:

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, &times);
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, &times);
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);

结果可能如下所示:


推荐阅读