OpenGL使用鼠标点击与鼠标光标移动的回调时出现未处理的异常

OpenGL Unhandled exception when using callbacks from mouse clicks vs mouse cursor moves

本文关键字:鼠标 回调 异常 未处理 光标 OpenGL 移动      更新时间:2023-10-16

在提问之前,我将公开部分代码以更好地解释它。

我使用OpenGL 3.3GLFW来处理鼠标上的事件。

我有我的OpenGL class:

class OpenGL
{
public:
    OpenGL();
    ~OpenGL();
private:
    //(...)
    void registerCallBacks();
    static void mouseMove(GLFWwindow* window, double xpos, double ypos);
    static void mouseClick(GLFWwindow* window, int button, int action, int mods);
    GLFWwindow*     m_window;
};

其中,我为鼠标事件注册callbacks

void OpenGL::registerCallBacks()
{
    glfwSetWindowUserPointer(m_window, this);
    glfwSetCursorPosCallback(m_window, mouseMove);
    glfwSetMouseButtonCallback(m_window, mouseClick);
}

从回调调用的方法如下(头文件上的static):

void OpenGL::mouseMove(GLFWwindow* window, double xpos, double ypos)
{
    void* userPointer = glfwGetWindowUserPointer(window);
    Mouse* mousePointer = static_cast<Mouse*>(userPointer);
    mousePointer->move(xpos,ypos); //EXECUTE MOVE AND CRASH on glfwSwapBuffers()
}
void OpenGL::mouseClick(GLFWwindow* window, int button, int action, int mods)
{
    void* userPointer = glfwGetWindowUserPointer(window);  
    Mouse* mousePointer = static_cast<Mouse*>(userPointer);
    mousePointer->click(button,action); //EXECUTE CLICK AND IT'S OK!!
}

正如你所看到的,我有一个处理鼠标事件的鼠标类:

class Mouse
{
public:
    Mouse();
    ~Mouse();
    void click(const int button, const int action); //called from the mouseClick() in the OpenGL class
    void move(const double x, const double y); //called from the mouseMove()  in the OpenGL class
private:
    double m_x;
    double m_y;
};

其中move方法仅为:

void Mouse::move(const double x, const double y)
{
    m_x = x;
    m_y = y;
}

click的方法只有这个:

void Mouse::click(const int button, const int action)
{
    printf("button:%d, action:%dn",button, action);
}

我的问题是:

我的openGL主循环在循环的末尾有一个:glfwSwapBuffers(m_window);,如果我使用如上所示的Mouse::move()方法,它将在这一行崩溃。如果我对move()方法的内容进行评论,则完全没有问题。

我甚至可以从click()中正确地看到printf's

我看不出move()和click()方法之间有什么区别。。。

这里发生了什么?为什么只有当我使用move()时,glfwSwapBuffers(m_window);才会出现崩溃?为什么不在click()中,因为两者都是以相同的方式构建的,使用各自的callbacks

注意:我确实需要使用move()方法来"保存"鼠标坐标,以便以后在click()方法上使用。

错误:

Unhandled exception at 0x001F2F14 in TheGame.exe: 0xC0000005: Access violation reading location 0x4072822C.

您将GLFW的用户指针设置为OpenGL类对象的this,但在回调中,您将其强制转换为Mouse类。这些类之间也没有继承关系,因此通过该指针访问任何成员变量或方法都会导致未定义的行为,在您的情况下,这种行为表现为崩溃。