所以我正在OpenGL中尝试在单击的点之间绘制线。如果我按下鼠标左键,绘图就会出现在屏幕上,但如果我松开鼠标左键则会消失:
struct Vector {
float x, y;
Vector(float x = 0, float y = 0) : x(x), y(y) {}
} last_mouse_pos;
void onInitialization() {
glClearColor(0, 0, 0, 0); // A hatterszin beallitasa.
glClear(GL_COLOR_BUFFER_BIT); // A kepernyo torlese, az uj hatterszinnel.
}
void onDisplay() {
glutSwapBuffers();
}
Vector convertToNdc(float x, float y) {
Vector ret;
ret.x = (x - kScreenWidth / 2) / (kScreenWidth / 2);
ret.y = (kScreenHeight / 2 - y) / (kScreenHeight / 2);
return ret;
}
int i = 0;
void onMouse(int button, int state, int x, int y) {
if (button == GLUT_RIGHT_BUTTON && state == GLUT_DOWN) {
glClear(GL_COLOR_BUFFER_BIT);
glutPostRedisplay();
}
else if (button == GLUT_LEFT_BUTTON) {
if (state == GLUT_DOWN) {
i++;
if (i == 1) last_mouse_pos = convertToNdc(x, y);
if (i > 1) {
Vector pos = convertToNdc(x, y);
glBegin(GL_LINES);
glVertex2f(last_mouse_pos.x, last_mouse_pos.y);
glVertex2f(pos.x, pos.y);
glEnd();
glutPostRedisplay();
last_mouse_pos = pos;
}
}
}
}
所以我得了2分,如果我一直按左键,它就会画出一条线,如果我松开它,屏幕就会变黑。如果我在其他地方点击,现在我有两行,但前提是我按下左键。如果我释放,所有的都会再次变黑。
是的,这里的方法有很多错误。在几乎所有情况下,绘制函数都应该是数据驱动的(即数据控制绘制的内容,除了数据什么都没有!(。大致如下:
// use this vector to store all of the point clicks
std::vector<Vector> points;
void onDisplay() {
// now just render each vertex making up the lines
glBegin(GL_LINES);
for(auto p : points)
glVertex2f(p.x, p.y);
glEnd();
glutSwapBuffers();
}
接下来,您需要跟踪鼠标的状态,因此为了尽可能简单(您可能想跟踪鼠标位置和其他按钮状态,但这是一个最小的例子(。
bool leftHeld = false;
下一步,您的鼠标功能将执行以下操作:
- 按下左键时,将新顶点添加到点阵列中
- 释放左键后,更新阵列中最后一个点的位置
- 当按下右侧按钮(而未按下左侧按钮(时,清除点阵列
void onMouse(int button, int state, int x, int y) {
switch(button) {
case GLUT_LEFT_BUTTON:
{
leftHeld = state == GLUT_DOWN;
if(leftHeld)
{
points.push_back(convertToNdc(x, y)); // add new point
}
else
points.back() = convertToNdc(x, y); // update last point
}
break;
// on right click, empty the array
// (but only if the left mouse button isn't currently pressed!)
case GLUT_RIGHT_BUTTON:
if(!leftHeld && state == GLUT_DOWN)
points.clear();
break;
}
glutPostRedisplay();
}
最后,如果你想在屏幕上点击和拖动时看到线条的更新,你需要注册一个鼠标移动功能来更新阵列中的最后一点
// register with glutMotionFunc.
// code updates last coordinate whilst mouse is moving, and
// the left button is held.
void onMouseMove(int x, int y) {
if(leftHeld)
{
points.back() = convertToNdc(x, y);
}
glutPostRedisplay();
}