gpt4 book ai didi

java - OpenGL 着色器 - 围绕原点旋转模型(2D 世界)

转载 作者:行者123 更新时间:2023-12-02 15:35:54 27 4
gpt4 key购买 nike

所以我创建了一个顶点着色器,它接受一个角度并计算旋转。尽管模型围绕世界中心而不是它自己的轴/原点旋转,但存在一个问题。

旁注:这是 2D 旋转。

如何让模型绕着自己的轴旋转?

这是我当前的顶点着色器:

#version 150 core

in vec4 in_Position;
in vec4 in_Color;
in vec2 in_TextureCoord;

out vec4 pass_Color;
out vec2 pass_TextureCoord;

void main(void) {


gl_Position = in_Position;

pass_Color = in_Color;
pass_TextureCoord = in_TextureCoord;
}

旋转 CPU 端:

    Vector3f center = new Vector3f(phyxBody.getPosition().x,phyxBody.getPosition().y,0);
Matrix4f pos = new Matrix4f();
pos.m00 = (phyxBody.getPosition().x)-(getWidth()/30f/2f);
pos.m01 = (phyxBody.getPosition().y)+(getHeight()/30f/2f);
pos.m10 = (phyxBody.getPosition().x)-(getWidth()/30f/2f);
pos.m11 = (phyxBody.getPosition().y)-(getHeight()/30f/2f);
pos.m20 = (phyxBody.getPosition().x)+(getWidth()/30f/2f);
pos.m21 = (phyxBody.getPosition().y)-(getHeight()/30f/2f);
pos.m30 = (phyxBody.getPosition().x)+(getWidth()/30f/2f);
pos.m31 = (phyxBody.getPosition().y)+(getHeight()/30f/2f);

pos.rotate(phyxBody.getAngle(),center);

结果是物体奇怪的旋转拉伸(stretch)。你知道为什么吗?不要担心/30f 部分。

  • phyxBody 是 JBox2D 库中 Body 类的一个实例。phyxBody.getAngle() 在 raidians 中。
  • Matrix4f 是 LWJGL 库中的一个类。

编辑:

    Vector3f center = new Vector3f(0,0,0);
Matrix4f pos = new Matrix4f();
pos.m00 = -(getWidth()/30f/2f);
pos.m01 = +(getHeight()/30f/2f);
pos.m10 = -(getWidth()/30f/2f);
pos.m11 = -(getHeight()/30f/2f);
pos.m20 = +(getWidth()/30f/2f);
pos.m21 = -(getHeight()/30f/2f);
pos.m30 = +(getWidth()/30f/2f);
pos.m31 = +(getHeight()/30f/2f);

pos.rotate(phyxBody.getAngle(),center);

pos.m00 += phyxBody.getPosition().x;
pos.m01 += phyxBody.getPosition().y;
pos.m10 += phyxBody.getPosition().x;
pos.m11 += phyxBody.getPosition().y;
pos.m20 += phyxBody.getPosition().x;
pos.m21 += phyxBody.getPosition().y;
pos.m30 += phyxBody.getPosition().x;
pos.m31 += phyxBody.getPosition().y;

目前这是转换代码,但旋转仍然不能正常工作。

我尝试旋转方法:(我做错了什么?)

    if (phyxBody.getAngle() != 0.0) {
pos.m00 *= Math.cos(Math.toDegrees(phyxBody.getAngle()));
pos.m01 *= Math.sin(Math.toDegrees(phyxBody.getAngle()));
pos.m10 *= -Math.sin(Math.toDegrees(phyxBody.getAngle()));
pos.m11 *= Math.cos(Math.toDegrees(phyxBody.getAngle()));
pos.m20 *= Math.cos(Math.toDegrees(phyxBody.getAngle()));
pos.m21 *= Math.sin(Math.toDegrees(phyxBody.getAngle()));
pos.m30 *= -Math.sin(Math.toDegrees(phyxBody.getAngle()));
pos.m31 *= Math.cos(Math.toDegrees(phyxBody.getAngle()));
}

最佳答案

顺序是缩放 * 旋转 * 平移 - 参见 this question .我猜你已经在你的着色器之外翻译了你的坐标。你必须先旋转,然后平移。了解您正在做的事情背后的线性代数是很好的,这样您就可以知道为什么事情有效或无效。

执行此操作的典型方法是传递已处理缩放/旋转/平移的预计算 ModelView 矩阵。如果您已经翻译了您的顶点,您将无法修复着色器中的问题,除非不必要地撤消它然后重做。发送未翻译的顶点,并附上数据(例如您的角度)来翻译它们。 或者您可以事先平移和旋转两者。这取决于你想做什么。

底线:您必须在翻译前旋转。

这是进行顶点变换的典型方法:

OpenGL 方面:

  1. 计算 ModelView 矩阵:缩放 * 旋转 * 平移

  2. 作为统一矩阵传递给着色器

GLSL 端:

  1. 在顶点着色器中将顶点乘以 ModelView 矩阵

  2. 发送到gl_Position

对编辑的回应:

我倾向于认为您的实现需要完全重做。您有属于模型的点。这些点都围绕着原点。例如,如果您有一辆车,这些点将形成一个三角形网格。

  • 如果您不平移这些点然后旋转它们,汽车将绕其中心旋转。如果您之后平移,汽车将以旋转方式平移到您指定的位置。这里的关键是模型的原点与旋转原点对齐,因此您最终会“围绕自身”旋转模型。

  • 如果您改为平移到新位置并然后旋转,您的模型将旋转,就好像它在绕原点旋转一样。这可能不是您想要的。

  • 如果您直接修改实际的顶点位置而不是使用变换矩阵,那您就错了。即使你只有一个正方形,也将坐标保留在 (-1,-1) (-1,1) (1,1) (1,-1) (注意中心如何位于 (0,0))和将它们翻译成你想去的地方。

  • 您不必重新实现数学功能,而且可能也不应该重新实现(除非您的目标明确表示要这样做)。 GLM 是一个流行的数学库,可以满足您的所有需求,并且专门为 OpenGL 量身定制。

最终编辑

这是我为您绘制的精美艺术作品,展示了您需要做什么。 enter image description here

  • 请注意右下角的模型是如何围绕 world 原点扫除大约 45 度的。如果我们再增加一个 45,它的底边将平行于 X 轴并与正 Y 轴相交,左下角的蓝色顶点和右下角的紫色顶点。

  • 您可能应该回顾一下如何使用顶点、矩阵和着色器。顶点应该被指定一次,矩阵应该在你每次改变对象的缩放、旋转或位置时更新,着色器应该将模型中的每个顶点乘以一个统一的(常量)。

关于java - OpenGL 着色器 - 围绕原点旋转模型(2D 世界),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17790245/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com