为啥我释放左键后我的绘图消失了?
Posted
技术标签:
【中文标题】为啥我释放左键后我的绘图消失了?【英文标题】:Why my drawings disappear after I release my left click?为什么我释放左键后我的绘图消失了? 【发布时间】:2019-11-06 23:43:14 【问题描述】:所以我试图在 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点,如果我按住左键,它会画线,如果我松开它,屏幕会变黑。如果我点击其他地方,现在我有 2 行,但前提是我按下左键。如果我释放,它会再次变黑。
【问题讨论】:
您可能收到了WM_ERASE
消息。
您的绘图仅发生在鼠标按下代码中。OpenGL 中的缓冲区被交换(在您的情况下:glutSwapBuffers
).. 您没有绘制每一帧,因此在下一帧时它会被擦除呈现。
如果我已经换了...为什么又换回来了?
不要在你的输入回调中绘制,锁定一些状态并通过glutPostRedisplay()
请求重新调用你的显示回调并在那里绘制。
【参考方案1】:
是的,你的方法有很多错误。在几乎所有情况下,您的绘图函数都应该是数据驱动的(即数据控制绘制的内容,而只有数据!)。大致如下:
// 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();
【讨论】:
以上是关于为啥我释放左键后我的绘图消失了?的主要内容,如果未能解决你的问题,请参考以下文章
为啥在取消 git 提交后我的更改消失了,我该如何恢复它们?