C ++ GLFW3输入处理 [英] C++ GLFW3 input handling

查看:91
本文介绍了C ++ GLFW3输入处理的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

因此,我一直在使用OpenGL + GLFW开发游戏引擎.最初,我一直在使用LWJGL包装器和Java.我决定将我的代码库移植到C ++.我一直通过像这样的lambda来使用"glfwSetCursorPosCallback"函数:

So I've been working on a game engine using OpenGL + GLFW. Originally I had been using the LWJGL wrappers and using Java. I've decided to port my codebase to C++. I had been making use of the "glfwSetCursorPosCallback" function via a lambda like so:

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

这样做使我可以将Engine类中的所有不同事件"联系在一起,并使GLFW设置代码+原始更新循环与其余引擎代码分开.保持Engine类的美观和干净.

Doing this allowed me to tie together all of the different "events" in the Engine class and keep the GLFW setup code + the raw update loop separate from the rest of the engine code. Leaving the Engine class nice and clean.

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

I would like to do the same thing using C++ however the following is invalid:

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

对于C ++ lambda,如果将lambda用作函数参数,则不能在"[]"块中传递任何内容.

With C++ lambdas you cannot pass anything in the "[]" block if the lambda is being used as a function parameter.

因此,我在最初的问题上进行了更多研究,我还阅读到使用lambda时性能较差.

So I was looking into it a bit more a on-top of that initial problem I also read that the performance was worse using lambdas.

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

So I tried passing the member function as the parameter instead:

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

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

Trying this also failed as you cannot pass an instanced classes member function as a parameter to glfwSetCursorPosCallback.

所以我问,我应该采取什么方法?是否有办法解决lambda/member函数的局限性,或者我完全不知道的完全不同的方法呢?

So I ask, what approach should I take? Is there ways to get around the lambda/member function limitations, or some totally different approach to this that I'm completely missing?

P.S. -我对C ++完全不了解,所以如果答案很明显,请原谅我.

P.S. - I'm quite out of practice with C++ so please forgive me if the answer is blatantly obvious.

为了帮助说明/阐明我要实现的目标,这是基于我以前的Java版本的Engine.h.

To help illustrate/clarify what I'm trying to achieve, this is the Engine.h based on my previous Java version.

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();
};

基本上,以main开头的GLFW回调/循环会触发带有"on"前缀的不同功能,以及其他可能的原因.这种方法是可行的,还是以某种方式在C ++中有更好的方法来实现,而C ++来自对象中所有东西都在Java中,这种思维方式是否对这种情况有缺陷?

Basically the different functions prefixed with "on" are fired off by the GLFW callbacks/loop in main, among potentially other things. Is this approach doable, somehow, or is there a better way of doing this in C++, coming from Java where everything is in Objects, is this mindset flawed for this situation?

推荐答案

使用 glfwSetWindowUserPointer() 设置给定窗口应在其上调用回调的Engine实例.

然后在(无需捕获的)lambda中调用 glfwGetWindowUserPointer() window,将void*强制转换为Engine*,然后调用相应的成员函数.

Then in the (capture-less) lambdas you can call glfwGetWindowUserPointer() with window, cast the void* to Engine*, and call the appropriate member function.

示例:

#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 );
}

这篇关于C ++ GLFW3输入处理的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆