OpenGL旋转和平移正确完成

OpenGL旋转和平移正确完成,opengl,vertex-shader,Opengl,Vertex Shader,谈到OpenGL中的旋转和平移,我有点卡住了 我得到了3个矩阵,投影,视图和模型 我的顶点着色器: gl_Position = projection * model * view * vec4(vertexData, 1); 平移和旋转对象的最佳方式是什么 将我的模型矩阵与平移和/或旋转矩阵相乘, 或者将数据(旋转和平移)传递到着色器和那里的数学 此外,我还需要知道mousepicking实现的“最终对象位置” 到目前为止,我所做的是这样的: object.Transformation =

谈到OpenGL中的旋转和平移,我有点卡住了

我得到了3个矩阵,投影,视图和模型

我的顶点着色器:

gl_Position =  projection * model * view * vec4(vertexData, 1);
平移和旋转对象的最佳方式是什么

将我的模型矩阵与平移和/或旋转矩阵相乘, 或者将数据(旋转和平移)传递到着色器和那里的数学

此外,我还需要知道mousepicking实现的“最终对象位置”

到目前为止,我所做的是这样的:

object.Transformation = Matrix.CreateTransLation(x,y,z) * Matrix.CreateRotation(x,y,z);

这是可行的,但感觉不对。做这件事最好的方法是什么?

这个

这是错误的。矩阵乘法不是可交换的,即运算顺序很重要。顶点位置上的变换顺序如下:

  • 模型
  • 看法
  • 投影
OpenGL使用的列向量矩阵乘法是左关联的,即从右向左。因此,语句R端的表达式应为

但是,您可以将视图和模型转换为复合模型视图(首先是模型,然后是视图)转换。这将保存完整的矩阵乘法

投影应保持分开,因为其他着色步骤可能需要顶点的眼睛空间位置,这是未应用投影的情况下
modelview*position
的结果

顺便说一句:您正在变换顶点位置,而不是数据。顶点由大量属性(不仅仅是位置)组成,因此将其称为“数据”在语义上是错误的

平移和旋转对象的最佳方式是什么

这些是modelview转换的一部分。您应该在CPU上创建一次转换矩阵,并将其传递给GPU。在着色器中执行此操作将强制GPU对每个顶点重新执行整个计算。你不想这么做

因评论而更新 假设你在用我的电脑。然后在绘图功能中为场景设置脚手架,即设置视口、构建投影和视图矩阵

#include <linmath.h>

/* ... */

void display(void)
{
     mat4x4 projection;
     mat4x4 view;

     glClear(…),
     glViewport(…);

     mat4x4_frustum(projection, …);

     // linmath.h doesn't have a look_at function... yet
     // I'll add it soon
     mat4x4_look_at(view, …);
现在,
model\u视图
包含完整的组件模型方向、平移和视图矩阵。我们现在需要做的就是绑定用于对象的着色器程序

         glUseProgram(obj->shader->program);
        object_draw(obj);
    }

/* ... */

}
穿上制服

         glUniformMatrix4f(obj->shader->location.projection, 1, GL_FALSE, projection);
         glUniformMatrix4f(obj->shader->location.modelview,  1, GL_FALSE, model_view);
         // and a few others...
然后画这个物体

         glUseProgram(obj->shader->program);
        object_draw(obj);
    }

/* ... */

}

谢谢你的意见。我现在会相应地改变,看看结果如何。虽然我不明白你写的最后一部分,但我该如何为物体创建平移和旋转呢?你能提供伪代码吗?
         mat4x4_mul(model_view, view, model_view);
         glUseProgram(obj->shader->program);
         glUniformMatrix4f(obj->shader->location.projection, 1, GL_FALSE, projection);
         glUniformMatrix4f(obj->shader->location.modelview,  1, GL_FALSE, model_view);
         // and a few others...
        object_draw(obj);
    }

/* ... */

}