我试图在这个程序中绘制多个矩形,但是每当我绘制一个新的矩形时,旧的矩形就会消失,我怎样才能在不丢失旧矩形的情况下绘制一个新的矩形?这是我的程序:
struct Position
{
Position() : x(0), y(0) {}
float x, y;
};
Position start, finish;
void mouse(int button, int state, int x, int y)
{
if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN)
{
start.x = finish.x = x;
start.y = finish.y = y;
}
if (button == GLUT_LEFT_BUTTON && state == GLUT_UP)
{
finish.x = x;
finish.y = y;
}
glutPostRedisplay();
}
void display()
{
glClear(GL_COLOR_BUFFER_BIT);
glBegin(GL_QUADS);
glVertex2f(start.x, start.y);
glVertex2f(finish.x, start.y);
glVertex2f(finish.x, finish.y);
glVertex2f(start.x, finish.y);
glEnd();
glFlush();
}
答案 0 :(得分:3)
创建一个类型来存储一个矩形:
struct Rect
{
Rect(const Position& s, const Position& f)
: start(s), finish(f) {}
Position start;
Position finish;
};
使用类型为 std::vector<Rect>
的容器来存储矩形
#include <vector>
std::vector<Rect> rects;
当一个矩形完成后,将其添加到容器中:
void mouse(int button, int state, int x, int y)
{
if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN)
{
start.x = finish.x = x;
start.y = finish.y = y;
}
if (button == GLUT_LEFT_BUTTON && state == GLUT_UP)
{
finish.x = x;
finish.y = y;
rects.emplace_back(start, finish);
start = finish;
}
glutPostRedisplay();
}
在一个循环中绘制所有矩形:
void display()
{
glClear(GL_COLOR_BUFFER_BIT);
glBegin(GL_QUADS);
for (auto& rect : rects)
{
glVertex2f(rect.start.x, rect.start.y);
glVertex2f(rect.finish.x, rect.start.y);
glVertex2f(rect.finish.x, rect.finish.y);
glVertex2f(rect.start.x, rect.finish.y);
}
glVertex2f(start.x, start.y);
glVertex2f(finish.x, start.y);
glVertex2f(finish.x, finish.y);
glVertex2f(start.x, finish.y);
glEnd();
glFlush();
}
此外,您还可以通过实现 glutMotionFunc
回调获得不错的绘图效果:
void motion(int x, int y)
{
finish.x = x;
finish.y = y;
glutPostRedisplay();
}
int main(int argc, char** argv)
{
// [...]
glutMotionFunc(motion);
// [...]
}
GL_LINE_LOOP
Primitive 的实现:
void display()
{
glClear(GL_COLOR_BUFFER_BIT);
for (auto& rect : rects)
{
glBegin(GL_LINE_LOOP);
glVertex2f(rect.start.x, rect.start.y);
glVertex2f(rect.finish.x, rect.start.y);
glVertex2f(rect.finish.x, rect.finish.y);
glVertex2f(rect.start.x, rect.finish.y);
glEnd();
}
glBegin(GL_LINE_LOOP);
glVertex2f(start.x, start.y);
glVertex2f(finish.x, start.y);
glVertex2f(finish.x, finish.y);
glVertex2f(start.x, finish.y);
glEnd();
glFlush();
}
答案 1 :(得分:2)
请注意,简单地删除 glClear
会导致您绘制的所有矩形持续在屏幕上 - 您将无法例如只删除其中之一。它还可能导致窗口的初始内容包含一些垃圾像素(尽管这可以通过在程序开始时执行 glClear
来解决)。
一个典型的解决方案是,正如 jackw11111 建议的那样,将所有矩形坐标存储在某个数据结构中(std::vector
是一个完美的选择,如果你使用 C++),并在你的 display
函数中您首先执行 glClear
,然后遍历所有矩形并一个一个地绘制它们。类似的东西
struct Rectangle
{
Position start, finish;
};
std::vector<Rectangle> rectangles;
void display()
{
glClear(GL_COLOR_BUFFER_BIT);
glBegin(GL_QUADS);
for (Rectangle const & r : rectangles)
{
glVertex2f(r.start.x, r.start.y);
glVertex2f(r.finish.x, r.start.y);
glVertex2f(r.finish.x, r.finish.y);
glVertex2f(r.start.x, r.finish.y);
}
glEnd();
}
顺便说一下,您几乎绝对不需要glFlush
。