Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Delphi OpenGL多重矩阵转换_Delphi_Opengl_Matrix - Fatal编程技术网

Delphi OpenGL多重矩阵转换

Delphi OpenGL多重矩阵转换,delphi,opengl,matrix,Delphi,Opengl,Matrix,我有用于模型的简单顶点着色器 #version 330 layout(location = 0) in vec3 VertexPosition; layout(location = 1) in vec3 VertexNormal; layout(location = 2) in vec2 VertexUV; out VS_GS_VERTEX { vec3 vs_worldpos; vec3 vs_normal; vec2 VertexUV; } vertex_out;

我有用于模型的简单顶点着色器

#version 330

layout(location = 0) in vec3 VertexPosition;
layout(location = 1) in vec3 VertexNormal;
layout(location = 2) in vec2 VertexUV;

out VS_GS_VERTEX
{
    vec3 vs_worldpos;
    vec3 vs_normal;
    vec2 VertexUV;
} vertex_out;

uniform mat4 modelMatrix;
uniform mat4 projectionMatrix;
uniform mat4 lookAtMatrix;

void main(void)
{
    mat4 MVP = projectionMatrix * lookAtMatrix * modelMatrix;

    gl_Position = MVP * vec4(VertexPosition, 1.0);
    gl_Normal = mat3(modelMatrix) * VertexNormal;

    vertex_out.vs_worldpos = gl_Position.xyz;
    vertex_out.vs_normal = gl_Normal;
    vertex_out.VertexUV = VertexUV;
}
我从那里经过

  modelMat := MatrixMultiply(transMat, baseMat);
  modelMat := MatrixMultiply(modelMat, scaleMat);
  modelMat := MatrixMultiply(modelMat, rotMat);
  glUniformMatrix4fv(modelMatrix_loc, 1, false, @modelMat);
其中transMat用于定位,scaleMat用于放大整个图片,rotMat用于旋转整个地形。 当baseMat是模型在地形上的坐标时,一切都很好

baseMat := CreateTranslationMatrix(AffineVectorMake(pos.x, pos.y, pos.z));
但当我试图通过自己的模型比例放大模型时(模型有零坐标,例如(0,0,0)处的树根)

模型不仅放大了,还改变了坐标,不再放在地形上。 是否可以使用模型的缩放、旋转、平移和另一个平移、缩放和旋转制作一个模型矩阵?还是我应该做点别的?来自
GLScene
的矩阵数学似乎很好

编辑:我不能通过先缩放矩阵来使用
正确的顺序
,因为我有这个


地形的结构是由64x64块组成的分块,每个块都有基本坐标。所以要把它放在一起,我首先需要将每个块翻译到适当的位置,然后缩放以放大图像并用鼠标旋转。 每个模型还具有指定给地形的绝对位置。我应该缩放和旋转模型(拥有模型的修改器),并将其放置在地形上的适当位置
transMat
(将瓷砖和模型放在屏幕中央),
scaleMat
rotMat
为地形和模型共享。但是本地
scMat
trMat
用于放大模型并将其放置在正确的位置

如果我使用
rotMat*scaleMat*transMat
让地形保持原样,但使用
rotMat*transMat*trMat*scaleMat*scMat
的模型,我有这个
再近一点

Edit2:将顶点着色器更改为

uniform mat4 modelMatrix;
uniform mat4 MVP;

void main(void)
{
    vec4 modelPos = modelMatrix * vec4(VertexPosition, 1.0);
    gl_Position = MVP * modelPos;
    gl_Normal = mat3(modelMatrix) * VertexNormal;

    vertex_out.vs_worldpos = gl_Position.xyz;
    vertex_out.vs_normal = gl_Normal;
    vertex_out.VertexUV = VertexUV;
}
通过

modelMatrix = modelRotMat * modelScaleMat;
mvpMatrix = projMat * lookAtMat * rotMat * scaleMat * modelTransMat * transNat;

现在它可以按预期工作了,谢谢您的帮助。

您必须在转换之前应用缩放。应用矩阵的正确顺序是

FinalMatrix = TranslationMatrix * RotationMatrix * ScaleMatrix;
(在特定情况下,您可以切换旋转和平移,具体取决于您希望旋转的对象,但通常是这样) 所以,如果你想把它们结合起来,你必须这样做

FinalMatrix = TranslationMatrix1 *TranslationMatrix2* RotationMatrix1 * RotationMatrix2 * ScaleMatrix1*ScaleMatrix2;
编辑

因此,您的模型在地形上具有基准位置旋转和缩放。您需要不时地向它们添加其他变换。你需要很多矩阵。 根据模型地形上的基准坐标,计算
TranslationMatrix2
。 您的
CreateTranslationMatrix(AffineVectorMake(pos.x,pos.y,pos.z))
应该可以。 您的模型在地形上的基本比例和旋转也应该在
RotationMatrix2
ScaleMatrix2
中。这三个矩阵保持每个模型在地形上的基本比例位置和方向。您的最终模型矩阵将是

ModelMatrix =  TranslationMatrix2 *RotationMatrix2 * ScaleMatrix2;
当您要缩放它们或将它们从该位置移动时,可以使用公式将新变换与这些变换结合起来。假设您要应用第二个刻度、新的旋转和新的平移,其矩阵是
ScaleMatrix1
RotationMatrix1
TranslationMatrix1
。您的最终模型矩阵为:

ModelMatrix =  TranslationMatrix1 *TranslationMatrix2*RotationMatrix1 * RotationMatrix2 * ScaleMatrix1*ScaleMatrix2;
EDIT2

如果你想保持地形的结构,我认为你必须用地形的比例矩阵来缩放模型的位置。然后,从该位置计算模型的平移矩阵。使用共享旋转矩阵和模型自己的比例,如下所示

pos = scaleMat * pos;
trMat = CreateTranslationMatrix(AffineVectorMake(pos.x, pos.y, pos.z));
ModelMatrix = SharedRotation* scMat * trMat ;

结果看起来很奇怪:模型像点,放大后会快速增长(分配给鼠标滚轮)。可能是因为原始地形逻辑是:平移->缩放->旋转。当我做地形矩阵数学时,比如缩放->平移->在某个点旋转,我可以捕捉到树木在正确大小和位置的图片。但贴图块会分别分割和缩放。让像terrain这样的模型一起平移->
所有比例
->
所有旋转
工作!几乎:(很多树仍在飞翔。我无法将逻辑更改为缩放->平移->旋转,因为我的地形不适合模型或分割。@user2091150缩放->平移->旋转是应用任何变换的正确方式。这是一个数学问题,而不是取决于你使用的算法的选择。我将编辑我的答案,并提供更多详细信息。正确的选择不是吗?)顺序取决于旋转是关于什么的。是关于原始原点还是翻译原点?@DavidHeffernan当然。但3D建模程序的工作方式总是缩放、旋转、平移。顺便说一下,这里的问题不是旋转与平移,而是平移与缩放,正确的顺序是缩放、平移问题是地形的构造方式需要平移,然后缩放,这是模型无法使用的顺序。
pos = scaleMat * pos;
trMat = CreateTranslationMatrix(AffineVectorMake(pos.x, pos.y, pos.z));
ModelMatrix = SharedRotation* scMat * trMat ;