如何在 OpenGl 中单独移动 2D 多个绘制形状(正方形和矩形)?

问题描述 投票:0回答:1

我刚刚开始在 Visual Studio 中使用 OpenGl。

我使用

drawsquare()
drawRoundRect () 
在单独的 void 函数中绘制多个形状,我在另一个名为 Display (void 返回类型)的函数中单独调用该函数,然后使用
glutDisplayFunc(Display)
在 int main 中调用该函数来显示。

在显示功能中,我使用

glutPushmatrix()
glutPopMatrix ()
保持 1 个形状的功能,如下所示

glutPushmatrix();
glutTranslatef(x,y,0); // z = 0 because i am making 2D shape
DrawSquare(50, 50, 50, colors[BALCK]); 
glutPopMatrix ();
glutPushmatrix();
glutTranslatef(x,y,0); // z = 0 because i am making 2D shape
DrawSquare(300, 300, 50, colors[BALCK]); 
glutPopMatrix ();

问题是,当我在屏幕上的任意位置单击鼠标(即使不在形状上)时,这两个形状都会开始一起移动。

Q1) 如何仅当鼠标在特定形状上单击并拖动时才能将形状逐个移动?

Q2)我应该怎么做才能使形状仅在单击和拖动时移动,而当我单击屏幕上的其他任何位置时什么也不会发生。

我使用了

glutPushMatrix()
glutPopMatrix()
glTranslatef ()
函数,这些函数对于移动一个形状效果很好,但我不知道如何仅在单击和拖动多个形状时才能移动它们。

glutPushmatrix();
glutTranslatef(x,y,0); // z = 0 because i am making 2D shape
DrawSquare(50, 50, 50, colors[BALCK]); 
glutPopMatrix ();
glutPushmatrix();
glutTranslatef(x,y,0); // z = 0 because i am making 2D shape
DrawSquare(300, 300, 50, colors[BALCK]); 
glutPopMatrix ();

使用此代码,我的两个人物一起移动而不是单独移动。 此外,即使鼠标没有单击任何形状,它们也会开始移动。

c++ opengl 2d-games opengl-3 opengl-4
1个回答
0
投票

您需要使用不同的 x,y 值。因为您使用相同的 x,y 值(相同的变量),所以它们将以相同的速率朝相同的方向移动,因为 x,y 是相同的位置。

您可以:

a)使用两组坐标,即x1,y1,x2,y2,并以不同的方式更新它们

b) 或者使用两组改变平移的偏移坐标,即 x1,y1, x2,y2 并将它们添加到 x,y。

对象应该存储在场景图中,无论是 2D 还是 3D。 2D 场景图基本上是按绘制顺序存储的对象数组。

例如,创建一个“实体”类,然后该类的一部分是坐标“位置”..即:

class Entity { // a base class for objects
 public:
  double x,y,z;
  double r,g,b,a;
  Entity() { r=g=b=a=x=y=z=0.0; }
  virtual void Render() {
   // do your gl drawing here, push and pop
  }
  virtual void RenderOffscreenForPicking() { /* ... different for drawing for a different reason ... */ }
};

上面的示例将是一个单一的“对象”,并且还应该包含您正在绘制的几何图形。它将包含一个识别颜色,对单个位置的单个对象进行渲染。

// object 1
glutPushmatrix();
glutTranslatef(x+x1,y+y1,0); // assuming x,y is the mouse, x1,y1 is the offset of object 1
DrawSquare(300, 300, 50, colors[BALCK]); 
glutPopMatrix ();
// object 2
glutPushmatrix();
glutTranslatef(x+x2,y+y2,0); // assuming x,y is the mouse, x2,y2 is the offset of object 2
DrawSquare(300, 300, 50, colors[BALCK]); 
glutPopMatrix ();

Q1) 如何仅通过鼠标单击来逐个移动图形 并拖动到特定形状?

Q2)我应该怎么做才能使形状仅在单击时移动 并拖动,当我单击上的其他任何位置时没有任何反应 屏幕。

这两个问题的答案都需要使用一个称为“挑选”的概念 - 有许多不同的挑选方法。如果您的对象是“轴对齐边界框”(矩形)并且 x,y 值与屏幕坐标具有相同的范围/比例,则可以使用简单的 AA 框测试(伪代码):

selected_object=null;
if ( mx > object1_x && my > object1_y && mx < object1_x+object1_width && my < object1_y+object1_height ) selected_object=object1;

另一种拾取方法是为每个对象分配一种颜色,在帧缓冲区(离屏缓冲区)上绘制对象。

  1. 首先使用“读回”测试帧缓冲区上的鼠标位置(mx,my),检查读回像素的颜色,然后使用它来确定单击了哪个对象。
  2. 单击时,确定单击了哪个对象后,将所选对象保存在变量中,当鼠标移动时,将对象移动鼠标增量(上一帧的鼠标位置与当前帧的鼠标位置之间的差值)帧的鼠标位置)直到释放鼠标按钮。

这种方法的优点是,对象的选择是“像素完美”的,而不是由方框决定的,如果对象被遮挡(“在另一个对象后面”),您仍然可以拾取它。

另请参阅:https://www.lighthouse3d.com/tutorials/opengl-selection-tutorial/#:~:text=The%20selection%20can%20be%20performed,object%20with%20a%20specific%20color

旁注,如果您不熟悉使用 OpenGL,您可能希望避免使用 *f 函数并使用 *d 函数,例如

glTranslated()
而不是
glTranslatef()
,因为它们使用双精度,而不是浮点.

© www.soinside.com 2019 - 2024. All rights reserved.