4

我不知道描述它的正确术语,这就是为什么我在 Google 中找不到它。我想要的只是缩放对象,特别是 2D 矩形,但将其保持在其 XY 坐标上。

我目前的解决方案是这样的:

glTranslatef(x, y, 0);
glScalef(scaleX, scaleY, 0);
glTranslatef(-x, -y, 0);
drawRect(x, y, width, height, texture);

我只是将 glScale 假装为 glRotate 在其中心旋转,它有点工作,但我可以看到它的坐标在缩放到其他值时的微小调整。

而且,更好的做法是 glTranslate 或仅在顶点上应用诸如 x,y 之类的变量。从这两个切换时我看不出有什么区别,但我担心添加“推送和弹出矩阵”会影响场景中其他对象的行为和我的程序的性能,因为我将使用很多这样的矩形。

更新:

所以你可以想象我想要实现的简单程度

adobe photoshop 处于最佳状态

4

2 回答 2

4

我想 < x, y, 0> 是矩形左下角在“规范”坐标系中的位置(我的意思是我们开始的那个)。

有了这些假设,您可以通过将模型视图堆栈重置为身份来实现您的目标,然后在进行缩放之前移动到对象空间。因此,您确实非常接近,但根据您之前对模型视图矩阵所做的操作,您可能会遇到结果的变化。

下面的代码应该做你想做的事:

glPushMatrix();
glLoadIdentity();
glTranslatef(x, y, 0);
// now in "object space"
glScalef(scaleX, scaleY, 0);
drawRect(0, 0, width, height, texture);
glPopMatrix();

我不知道该draw函数的作用,但我想它只是发出一堆glVertexglTexCoord调用,即。它不会干扰模型视图矩阵,否则我的代码很可能会破坏它。

请注意,如果您使用glPushMatrixandglPopMatrix调用包装所有对象渲染,则不需要该glLoadIdentity调用,甚至可能适得其反。例如,如果您将对象数据组织为层次结构,每个子对象相对于其容器定位,那么您将需要在递归渲染对象层次结构时完全删除该调用。

另一个问题是效率问题。保存和恢复矩阵是相当昂贵的操作。鉴于您的问题代码使用的是立即模式,我认为这不是您主要关心的问题。手动应用对象转换肯定会更快(即通过使用您自己的矩阵库计算它们),并将它们提交给 opengl,而无需调用 opengl 模型视图操作例程。但是,这应该由另一个(更面向数学的)问题和答案来涵盖。

于 2013-06-21T05:37:30.600 回答
0

保持点固定的按角度旋转的一般模式phi(也适用于其他仿射变换)是(x,y)

TRANSLATE(-x, -y)
ROTATE(phi)
TRANSLATE(x, y)

转换按从上到下的顺序应用。所以你将点移动(x,y)到原点(0,0)。因此它不会受到实际旋转的影响。完成后,第二个翻译会反转第一个翻译的效果。

这不仅限于 OpenGL,而是适用于支持仿射变换(通过矩阵或四元数)的任何类型的图形处理。

于 2013-06-21T08:25:20.473 回答