使用 glm 平移对象,使其跟随鼠标光标
Translating the object with glm so that it follows the mouse cursor
这就是我想要做的。我想用我的鼠标实现翻译,这样我正在翻译的对象将跟随我的鼠标移动,即如果我的鼠标光标移动一定数量的像素 X,我希望对象移动完全相同的数量 X。
到目前为止,对于旋转,我一直在使用 glm 来实现 arcball,因此我得到了一个旋转矩阵。
我正在使用 openGL 和 SDL,因此获取鼠标坐标并不困难。
我可以在鼠标运动事件期间使用当前鼠标坐标创建大小为 3 的向量:
while (SDL_PollEvent(&event))
{
switch (event.type)
{
case SDL_MOUSEMOTION:
glm::vec3 vecTranslation(event.motion.x, event.motion.y, 0);
glm::mat4 translationMatrix ;
glm::translate(translationMatrix, vecTranslation) ;
}
}
这样我就有了一个翻译矩阵,但是这不会让我得到一个完全按照鼠标光标最后所做的事情的翻译。
有没有人对此有一些见解?
此外,为了获得我的最终投影矩阵以便调用 glMulMatrix()
,我这样做:
glm::matrixCompMult(translationMatrix,rotationMatrix);
但是当我这样做时,平移和旋转都不起作用。如果我简单地 return 旋转矩阵并直接将它与 glMulMatrix()
一起使用,我的 arcball 会按预期运行,但是如果我使用上面的代码,我只能看到我拥有的立方体的一个面不断改变它的比例,但从不旋转也不平移。
至于我用于绘图的代码:
//假设完成了一些代码来知道是否应该进行翻译以及应该进行哪些翻译
matrixProjection = translationMatrix * mMatNow * scaleMatrix ;
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glClear(GL_COLOR_BUFFER_BIT);
glMultMatrixf(矩阵投影);
//缩放转换
glScalef(0.5,0.5,0.5);
drawCube();
glFlush();
SDL_GL_SwapBuffers();
我得到的矩阵是这样的:
第一:
1; 0; 0; 0;
0; 1 ; 0; 0;
0; 0; 1 ; 0;
0; 0; 0; 1 ;
然后经过翻译:
1; 0; 0; 0;
0; 1 ; 0; 0;
0; 0; 1 ; -25 ;
0; 0; 0; 1 ;
显然翻译确实发生了,但是我在绘图上得到了这个奇怪的结果:
原图:
您知道您的鼠标追踪器和您要移动的对象的位置。
让对象跟随鼠标的最简单方法是将其位置设置为鼠标的位置:
一种方式:假设您将 vec3(10, 10, 4) 作为鼠标位置,然后只需设置
. . . 10
. . . 10
. . . 4
0 0 0 1
(你这个别写点)
作为对象矩阵。为此,您的鼠标位置必须不是 window 上的位置,而是世界上的位置。
另一种方式:
在你的顶点着色器中添加一个 in 变量,如下所示:
layout(location = 0) in vec3 inputPosition;
layout(location = 1) in vec3 inputOffset;
layout(location = 2) in vec4 inputColor;
out vec4 color;
uniform mat4 worldMatrix;
uniform mat4 viewMatrix;
uniform mat4 projectionMatrix;
void main(void)
{
gl_Position = worldMatrix * vec4(inputPosition + inputOffset, 1.0f);
gl_Position = viewMatrix * gl_Position;
gl_Position = projectionMatrix * gl_Position;
color = inputColor;
}
偏移量是您的鼠标位置向量。这种方法不会将对象附加到您的鼠标上,而是随鼠标一起移动。
此外,对于您不想移动的每个对象,您都需要另一个着色器。
编辑:
如果你想旋转它指向你的 courser 的对象,最简单的方法是将该对象的中间作为向量并计算鼠标位置和对象向量之间的距离。然后你可以做一些数学运算以获得正确的角度并旋转对象。
编辑2:
尝试以下操作:我也曾经遇到过翻译前的矩阵和翻译后的矩阵一样的问题。这是因为他确实覆盖了矩阵。
我做了什么:
首先,为了更容易,用你的对象的位置做一个 glm::vec3 。例如。 vec3(0,0,0)。
然后绘制你的四边形,它的中心位于屏幕的左上角。如果现在用鼠标位置更新四边形的位置向量,则鼠标代表四边形的中心。
所以每一帧你都做以下事情:
伪代码:
positionQuad.x = event.motion.x;
positionQuad.y = 0;
positionQuad.z = event.motion.y;
translationMatrix = glm::translate(positionQuad); // Declare translationMatrix as global/class variable to have access anywhere. glm translate multiplies the translation vector (vec4(mX, 0, mZ, 1) with an identity matrix. This works because we initialized the quad at upper left corner
render(); // translationMatrix now is the model matrix. in render you still have to build the MVP matrix and draw it like always.
旋转只需添加
glm::rotate(translationMatrix, DEGREES, glm::vec3(0,1,0)); //this changes the current model-matrix by rotating it by DEGREES degrees around the axis specified in the vec3. If you do it otherwise like translationMatrix= glm::rotate.... you would overwrite the Matrix and you wont have any translation anymore.
翻译之后渲染之前
这就是我想要做的。我想用我的鼠标实现翻译,这样我正在翻译的对象将跟随我的鼠标移动,即如果我的鼠标光标移动一定数量的像素 X,我希望对象移动完全相同的数量 X。
到目前为止,对于旋转,我一直在使用 glm 来实现 arcball,因此我得到了一个旋转矩阵。
我正在使用 openGL 和 SDL,因此获取鼠标坐标并不困难。 我可以在鼠标运动事件期间使用当前鼠标坐标创建大小为 3 的向量:
while (SDL_PollEvent(&event))
{
switch (event.type)
{
case SDL_MOUSEMOTION:
glm::vec3 vecTranslation(event.motion.x, event.motion.y, 0);
glm::mat4 translationMatrix ;
glm::translate(translationMatrix, vecTranslation) ;
}
}
这样我就有了一个翻译矩阵,但是这不会让我得到一个完全按照鼠标光标最后所做的事情的翻译。
有没有人对此有一些见解?
此外,为了获得我的最终投影矩阵以便调用 glMulMatrix()
,我这样做:
glm::matrixCompMult(translationMatrix,rotationMatrix);
但是当我这样做时,平移和旋转都不起作用。如果我简单地 return 旋转矩阵并直接将它与 glMulMatrix()
一起使用,我的 arcball 会按预期运行,但是如果我使用上面的代码,我只能看到我拥有的立方体的一个面不断改变它的比例,但从不旋转也不平移。
至于我用于绘图的代码: //假设完成了一些代码来知道是否应该进行翻译以及应该进行哪些翻译 matrixProjection = translationMatrix * mMatNow * scaleMatrix ; glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glClear(GL_COLOR_BUFFER_BIT); glMultMatrixf(矩阵投影); //缩放转换 glScalef(0.5,0.5,0.5); drawCube();
glFlush();
SDL_GL_SwapBuffers();
我得到的矩阵是这样的: 第一:
1; 0; 0; 0; 0; 1 ; 0; 0; 0; 0; 1 ; 0; 0; 0; 0; 1 ;
然后经过翻译:
1; 0; 0; 0; 0; 1 ; 0; 0; 0; 0; 1 ; -25 ; 0; 0; 0; 1 ;
显然翻译确实发生了,但是我在绘图上得到了这个奇怪的结果:
原图:
您知道您的鼠标追踪器和您要移动的对象的位置。
让对象跟随鼠标的最简单方法是将其位置设置为鼠标的位置:
一种方式:假设您将 vec3(10, 10, 4) 作为鼠标位置,然后只需设置
. . . 10
. . . 10
. . . 4
0 0 0 1
(你这个别写点) 作为对象矩阵。为此,您的鼠标位置必须不是 window 上的位置,而是世界上的位置。
另一种方式: 在你的顶点着色器中添加一个 in 变量,如下所示:
layout(location = 0) in vec3 inputPosition;
layout(location = 1) in vec3 inputOffset;
layout(location = 2) in vec4 inputColor;
out vec4 color;
uniform mat4 worldMatrix;
uniform mat4 viewMatrix;
uniform mat4 projectionMatrix;
void main(void)
{
gl_Position = worldMatrix * vec4(inputPosition + inputOffset, 1.0f);
gl_Position = viewMatrix * gl_Position;
gl_Position = projectionMatrix * gl_Position;
color = inputColor;
}
偏移量是您的鼠标位置向量。这种方法不会将对象附加到您的鼠标上,而是随鼠标一起移动。 此外,对于您不想移动的每个对象,您都需要另一个着色器。
编辑: 如果你想旋转它指向你的 courser 的对象,最简单的方法是将该对象的中间作为向量并计算鼠标位置和对象向量之间的距离。然后你可以做一些数学运算以获得正确的角度并旋转对象。
编辑2:
尝试以下操作:我也曾经遇到过翻译前的矩阵和翻译后的矩阵一样的问题。这是因为他确实覆盖了矩阵。 我做了什么: 首先,为了更容易,用你的对象的位置做一个 glm::vec3 。例如。 vec3(0,0,0)。 然后绘制你的四边形,它的中心位于屏幕的左上角。如果现在用鼠标位置更新四边形的位置向量,则鼠标代表四边形的中心。 所以每一帧你都做以下事情: 伪代码:
positionQuad.x = event.motion.x;
positionQuad.y = 0;
positionQuad.z = event.motion.y;
translationMatrix = glm::translate(positionQuad); // Declare translationMatrix as global/class variable to have access anywhere. glm translate multiplies the translation vector (vec4(mX, 0, mZ, 1) with an identity matrix. This works because we initialized the quad at upper left corner
render(); // translationMatrix now is the model matrix. in render you still have to build the MVP matrix and draw it like always.
旋转只需添加
glm::rotate(translationMatrix, DEGREES, glm::vec3(0,1,0)); //this changes the current model-matrix by rotating it by DEGREES degrees around the axis specified in the vec3. If you do it otherwise like translationMatrix= glm::rotate.... you would overwrite the Matrix and you wont have any translation anymore.
翻译之后渲染之前