C++ GLFW3 输入处理

C++ GLFW3 input handling

本文关键字:处理 输入 GLFW3 C++      更新时间:2023-10-16

所以我一直在使用OpenGL + GLFW开发游戏引擎。最初我一直在使用LWJGL包装器和Java。我决定将我的代码库移植到C++。我一直在通过lambda使用"glfwSetCursorPosCallback"函数,如下所示:

//Java:
glfwSetCursorPosCallback(win, (window, xpos, ypos) -> {
engine.onCursorMoved(xpos, ypos);
});

这样做使我能够将引擎类中的所有不同"事件"联系在一起,并将 GLFW 设置代码 + 原始更新循环与引擎代码的其余部分分开。让引擎类漂亮而干净。

我想用C++做同样的事情,但是以下内容无效:

glfwSetCursorPosCallback(window, [engine](GLFWwindow* window, double x, double y) {
engine.onCursorMoved(x, y);
});

使用 lambdaC++如果 lambda 用作函数参数,则无法在 "[]" 块中传递任何内容。

所以我在最初的问题之上进行了更多的研究,我还读到使用 lambda 的性能更差。

所以我尝试将成员函数作为参数传递:

// I changed "onCursorMoved" use the proper parameter signature
// "onCursorMoved(GLFWwindow* window, double x, double y)"
glfwSetCursorPosCallback(window, engine.onCursorMoved);

尝试此操作也失败了,因为您无法将实例化类成员函数作为参数传递给 glfwSetCursorPosCallback。

所以我问,我应该采取什么方法?有没有办法绕过lambda/成员函数的限制,或者一些我完全缺少的完全不同的方法?

附言 - 我对C++很不熟悉,所以如果答案显而易见,请原谅我。

编辑:为了帮助说明/澄清我想要实现的目标,这是基于我以前的Java版本的Engine.h。

class Engine {
private:
//member variables for scene graph, etc
public:
Engine();
~Engine();
public:
void onWindowResized(int width, int height);
void onCursorMoved(double x, double y);
void onUpdate(float timeStep);
void onRender();
};

基本上,以"on"为前缀的不同函数是由 GLFW 回调/循环在 main 中触发的,以及其他潜在的事情。这种方法是否可行,或者是否有更好的方法来做到这一点,C++,来自Java,一切都在对象中,在这种情况下,这种心态是否有缺陷?

使用glfwSetWindowUserPointer()设置给定窗口应调用回调的Engine实例。

然后在(无捕获的(lambda中,你可以用window调用glfwGetWindowUserPointer(),将void*转换为Engine*,并调用适当的成员函数。

例:

#include <GLFW/glfw3.h>
#include <cstdlib>
class Engine
{
public:
void onCursorPos( double x, double y )
{
mX = x;
mY = y;
}
double mX, mY;
};
int main()
{
if( !glfwInit() )
exit( EXIT_FAILURE );
glfwWindowHint( GLFW_CONTEXT_VERSION_MAJOR, 2 );
glfwWindowHint( GLFW_CONTEXT_VERSION_MINOR, 1 );
GLFWwindow* window = glfwCreateWindow( 640, 480, "Simple example", NULL, NULL );
Engine engine;
glfwSetWindowUserPointer( window, &engine );
glfwSetCursorPosCallback( window, []( GLFWwindow* window, double x, double y )
{
Engine* engine = static_cast<Engine*>( glfwGetWindowUserPointer( window ) );
engine->onCursorPos( x, y );
} );
glfwMakeContextCurrent( window );
glfwSwapInterval( 1 );
while( !glfwWindowShouldClose( window ) )
{
glClearColor( engine.mX / 640.0, engine.mY / 480.0, 1.0, 1.0 );
glClear( GL_COLOR_BUFFER_BIT );
glfwSwapBuffers( window );
glfwPollEvents();
}
glfwDestroyWindow( window );
glfwTerminate();
exit( EXIT_SUCCESS );
}

只需输入回调函数的名称:

//callbacks header file
void cursor_position_callback(GLFWwindow* window, double xpos, double ypos);
//GLFW init function
glfwSetCursorPosCallback(window, cursor_position_callback);