如何使对象在 Opengl 中沿用户定义的线移动
Posted
技术标签:
【中文标题】如何使对象在 Opengl 中沿用户定义的线移动【英文标题】:How to make an object move along a user-defined line in Opengl 【发布时间】:2016-10-14 14:50:01 【问题描述】:我的程序允许用户单击窗口上的任意位置,当按下 Enter 时,它会沿着这些点跟踪线。另外,当按下空格键时,它会在第一个点画一个三角形,我希望它沿着整条线移动到最后,然后回到起点,然后重复。
我在起点上进行了线跟踪和绘制三角形,我什至让平移运动开始工作。我唯一的问题是,无论这条线如何,它都会一直在右下角移动。这一定是我的方向,但我不知道出了什么问题。
首先这是我绘制三角形的方法。用户定义的点在名为 controlPoints 的 glm::vec3 变量中定义。所以我在第一个点创建三角形(然后它被传递到 VBO,绑定到 VAO,等等 [triangleVertices 也是一个 glm::vec3 变量]):
// Lower-left vertex
triangleVertices.push_back(glm::vec3(controlPoints[0].x - 30.0f, controlPoints[0].y + 30.0f, controlPoints[0].z));
// Lower-right vertex
triangleVertices.push_back(glm::vec3(controlPoints[0].x + 30.0f, controlPoints[0].y + 30.0f, controlPoints[0].z));
// Upper-center vertex
triangleVertices.push_back(glm::vec3(controlPoints[0].x, controlPoints[0].y, controlPoints[0].z));
// Bind VAO for the triangle
glBindVertexArray(VAOTriangle);
// Bind and implement VBO for the triangle
glBindBuffer(GL_ARRAY_BUFFER, VBOTriangle);
glBufferData(GL_ARRAY_BUFFER, triangleVertices.size() * sizeof(glm::vec3), triangleVertices.data(), GL_STATIC_DRAW);
// Connecting coordinates to shader
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (GLvoid*)0);
glEnableVertexAttribArray(0);
// Unbind VAO
glBindVertexArray(0);
然后在我的游戏循环中,我是这样进行转换的(模型矩阵已经乘以着色器中的位置,对象已经绑定到该位置):
glBindVertexArray(VAOTriangle);
float inputX = 0.0;
float inputY = 0.0;
GLfloat deltaTime = 0.0f;
GLfloat lastFrame = 0.0f;
GLfloat currentFrame = glfwGetTime();
deltaTime = currentFrame - lastFrame;
lastFrame = currentFrame;
GLfloat speed = 5.0f * deltaTime;
glm::vec2 direction;
for (int i = 0; i < controlPoints.size(); i++)
inputX = controlPoints[i].x;
inputY = controlPoints[i].y;
direction.x = inputX * float((speed * deltaTime) / 1000.0f);
direction.y = inputY * float((speed * deltaTime) / 1000.0f);
model_matrix = glm::translate(model_matrix, glm::vec3(direction, 0.0f));
glUniformMatrix4fv(transformLoc, 1, GL_FALSE, glm::value_ptr(model_matrix));
glDrawArrays(GL_TRIANGLES, 0, triangleVertices.size());
glBindVertexArray(0);
如果我将 glDrawArrays 放在 for 循环中,它会创建与点相同数量的三角形,这不是我想要的(只有 1 个三角形)。但是像这样,它看起来只需要最后一点的方向,因为它在整个循环结束后绘制。但它也没有这样做。就像我说的,它只是右下角(直到它从窗口中消失),无论线条结构如何。
编辑:
这是我关于如何沿线平移对象的新设置。不管我做什么,它仍然会朝着右下方向脱线。
glBindVertexArray(VAOTriangle);
// Getting time to define translation speed
GLfloat deltaTime = 0.0f;
GLfloat lastFrame = 0.0f;
GLfloat currentFrame = glfwGetTime();
deltaTime = currentFrame - lastFrame;
lastFrame = currentFrame;
GLfloat speed = 3.0f * deltaTime;
// Going through all points of the line
translationX = controlPoints[translationIndex].x;
translationY = controlPoints[translationIndex].y;
if (translationIndex < controlPoints.size() - 1)
translationIndex++;
translationIndex %= controlPoints.size();
// Update direction vector
translationDirection.x = translationX * float((speed * deltaTime) / 1000.0f);
translationDirection.y = translationY * float((speed * deltaTime) / 1000.0f);
model_matrix = glm::translate(model_matrix, glm::vec3(translationDirection, 0.0f));
glUniformMatrix4fv(transformLoc, 1, GL_FALSE, glm::value_ptr(model_matrix));
glDrawArrays(GL_TRIANGLES, 0, triangleVertices.size());
glBindVertexArray(0);
【问题讨论】:
【参考方案1】:您正在一次遍历整个 controlPoints 数组,并且只有最后一次调用 glUniformMatrix4fv 很重要。
您应该尝试做的是删除此 for 循环并增加一些值(每个帧或特定步骤),这将替换您的“i”变量。
【讨论】:
所以你说我删除了循环,我做了: 所以你说我删除了循环,在游戏循环之外定义 int i = 0,我这样做: inputX = controlPoints[i].x; inputY = controlPoints[i].y;我 = 我 + 1;如果是这样,程序就会崩溃。 你会限制值吗?它应该在 0 到 controlPoints.size() - 1 的范围内。在递增后尝试使用 i = i % controlPonts.size()。 好的,现在发生了同样的事情(只是移动了左下角),除了三角形 gitters,它更糟。你确定我的其他代码没问题吗? 索引增量多久发生一次?它的运行速度是否与渲染单帧一样快?请记住,这种方式可以运行 200 FPS,因此这意味着您的计数器在几分之一秒内达到最大值。由于您已经在使用时间获取器,请尝试添加一些“冷却时间”,您将检查该 if 条件。以上是关于如何使对象在 Opengl 中沿用户定义的线移动的主要内容,如果未能解决你的问题,请参考以下文章