OpenGL 3.0 窗口碰撞检测
Posted
技术标签:
【中文标题】OpenGL 3.0 窗口碰撞检测【英文标题】:OpenGL 3.0 Window Collision Detection 【发布时间】:2018-11-22 03:40:02 【问题描述】:谁能告诉我如何让三角形顶点与屏幕边缘发生碰撞? 对于数学库,我使用 GLM,对于窗口创建和键盘/鼠标输入,我使用 GLFW。 我创建了透视矩阵和简单的三角形顶点数组。
然后我在顶点着色器中将所有这些相乘:
gl_Position = projection * view * model * vec4(pos, 1.0);
投影矩阵定义为:
glm::mat4 projection = glm::perspective(
45.0f, (GLfloat)screenWidth / (GLfloat)screenHeight, 0.1f, 100.0f);
我的相机和投影功能可以正常工作。我可以在我的“世界”中移动并看到三角形站在那里。我遇到的问题是我想确保三角形与屏幕边缘发生碰撞。
我所做的是禁用相机,只启用键盘移动。然后我将平移矩阵初始化为glm::translate(model, glm::vec3(xMove, yMove, -2.5f));
,并将矩阵缩放为 0.4。
现在所有这些都运行良好。当我按下 RIGHT 时,三角形向右移动,当我按下 UP 时,三角形向上移动等......问题是我不知道如何让它停止移动,然后它会碰到边缘。
这是我尝试过的:
triangleRightVertex.x
是 glm::vec3
对象。
0.4 是我在缩放矩阵中使用的缩放值。
if(((xMove + triangleRightVertex.x) * 0.4f) >= 1.0f)
cout << "Right side collision detected!" << endl;
当我将三角形向右移动时,它会在第三个顶点(三角形的右下角)的 x 与右侧碰撞时检测到碰撞,但它在检测到之前稍微超出了一点。但是当我尝试向上移动时,当三角形的一半向上时它检测到碰撞。
我不知道该怎么做,有人可以解释一下吗?
【问题讨论】:
我的解决方案是创建线条作为窗框,并使用线条方程检查点是否在线条中。不知道好不好。 【参考方案1】:三角形的每个顶点坐标由model
矩阵从模型空间变换到世界空间,通过view
矩阵从世界空间变换到视图空间,通过projection
矩阵从视图空间变换到剪辑空间。 gl_Position
是剪辑空间中的Homogeneous coordinate,并通过Perspective divide 从剪辑空间进一步转换为规范化设备空间。标准化的设备空间是一个立方体,右、下、前在 (-1, -1, -1) 和左、上、后在 (1, 1, 1)。
此(体积)立方体中的所有几何图形在视口上都是“可见的”。
在剪辑空间中执行场景的剪辑。
如果x
、y
和z
分量在该点齐次坐标的倒置w
分量和w
分量定义的范围内,则该点位于裁剪空间中:
-w <= x, y, z <= w
您要做的是检查三角形的顶点x
坐标是否被剪裁。所以你必须检查剪辑空间坐标的x
分量是否在视图体积中。
计算 CPU 上顶点的剪辑空间位置,就像计算顶点着色器一样。 glm library 非常适合这样的事情:
glm::vec3 triangleVertex = ... ; // new model coordinate of the triangle
glm::vec4 h_pos = projection * view * model * vec4(triangleVertex, 1.0);
bool x_is_clipped = h_pos.x < -h_pos.w || h_pos.x > h_pos.w;
如果你不知道model
矩阵和view
矩阵是如何变换三角形的方向的,那么你必须对三角形的所有3个顶点坐标都这样做-
【讨论】:
嘿,非常感谢!我完全忘记了矩阵的 w 分量 -.- .. 我什至比较了纵横比,因为我不知道发生了什么哈哈。我正准备做线方程 /////以上是关于OpenGL 3.0 窗口碰撞检测的主要内容,如果未能解决你的问题,请参考以下文章