提问人:Wiki 提问时间:12/9/2022 最后编辑:FareanorWiki 更新时间:8/26/2023 访问量:69
如何在 OpenGL 中分别移动 2D 多个绘制的形状(正方形和矩形)?
How to move 2D multiple drawn shapes (Squares and Rectanagles) seperately in OpenGl?
问:
我刚刚开始在 Visual Studio 中使用 OpenGl。
我使用 and 在单独的 void 函数中绘制多个形状,我在另一个名为 Display(void 返回类型)的函数中单独调用该函数,然后在 int main 中调用该函数来显示。drawsquare()
drawRoundRect ()
glutDisplayFunc(Display)
在我使用的显示功能中,将 1 个形状的功能保持在两者之间,如下所示glutPushmatrix()
glutPopMatrix ()
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 ();
使用这段代码,我的两个图形一起移动,而不是分开移动。 此外,即使没有单击鼠标的任何形状,它们也会开始移动。
答:
您需要使用不同的位置值。由于您使用相同的 (x,y) 值(相同的变量),因此它们将以相同的速率沿同一方向移动,因为 (x,y) 是相同的位置。
// object 1
glutPushmatrix();
glutTranslatef(x1,y1,0); // x1,y1 is the position of object 1
DrawSquare(300, 300, 50, colors[BALCK]);
glutPopMatrix ();
// object 2
glutPushmatrix();
glutTranslatef(x2,y2,0); // x2,y2 is the position of object 2
DrawSquare(300, 300, 50, colors[BALCK]);
glutPopMatrix ();
但是,您可能需要一个包含对象并管理其数据的场景图。
对象应存储在场景图中,无论是 2D 还是 3D。2D 场景图基本上是按绘制顺序存储的对象数组。
例如,创建一个“实体”类,然后该类的一部分是坐标“位置”。结婚
class Entity { // a base class for objects
public:
double x,y,z,w,h; // position, size
int r,g,b; // identifying color rgba 0-255, unique to each object
Entity() { r=g=b=a=x=y=z=0.0; }
virtual void Render() {
// do your gl drawing here, push and pop
}
bool Within( double mx, double my ) { // return true if mx,my inside boundary
return (mx > x && my > y && mx < x+w && my < y+h );
}
virtual void RenderOffscreenForPicking() { /* ... different for drawing for a different reason ... */ }
};
上面的示例将是一个“对象”,并且还应该包含您正在绘制的几何图形。它将包含一种识别颜色,用于渲染单个位置的单个对象。这样的对象可以使用多态性进行扩展。它可以包括速度、方向、旋转和许多其他值,以定义行为、绘图样式、几何图形等。
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;
拾取的另一种方法是为每个对象分配颜色,在帧缓冲区(屏幕外缓冲区)上绘制对象。
- 首先,当用户 (mx,my) 首次在帧缓冲区上按下按钮时,使用“回读”测试鼠标位置,检查回读像素的颜色,然后使用它来确定单击了哪个对象。
- 单击时,在确定单击了哪个对象后,将所选对象保持在变量中,当鼠标移动时,通过鼠标增量(前一帧的鼠标位置与当前帧的鼠标位置之间的差值)移动对象,直到释放鼠标按钮。
这种方法的优点是对象的选择是“像素完美”的,不是由方框决定的,如果对象被遮挡(“在另一个对象后面”),你仍然可以拾取它。
旁注,如果您不熟悉使用 OpenGL,您可能希望避免使用 *f 函数并使用 *d 函数,例如代替 ,因为它们使用双精度,而不是浮点。glTranslated()
glTranslatef()
评论