2

I have a GLWindow class which is a wrapper for OpenGL. This class declares data types enum class that are the arguments of the callback function:

enum class Modifier
{
    NoModifier = 0,
    Shift = 1,
    Control = 2,
    Alt = 4,
    Super = 8,
};
enum class Action
{
    Release = 0,
    Press = 1,
    Repeat = 2,
};
enum class ButtonCode
{
    Button_0 = 0,
    //... repeats all buttons codes from the glfw header
};
enum class KeyCode
{
    UNKNOWN = -1,
    Space = 32,
    //.... repeats all key codes from the glfw header
};

Pointers to be passed to glfwSetKeyCallback as second parameter to std::function:

using KeyCallback = std::function<void(GLFWwindow* window, int key, int scancode, int action, int mode)>;
using CursorPosCallback = std::function<void(double, double)>;
using MouseCallback = std::function<void(ButtonCode, Action, Modifier, double, double)>;
using ScrollCallback = std::function<void(double, double)>;

On assignment, I have to declare a callback function in Main.cpp and through the GLWindow class pass a pointer to this function to glfwSetKeyCallback as the second parameter

Main.cpp:

void onKeyCallback(KeyCode key, Action action, Modifier mods)
{
    std::cout << "Key: " << glfwGetKeyName(key, 0) << " is pressed." << std::endl;
}

int main()
{
...
GLWindow window("myWindow", 640, 480);
window.setKeyCallback(onKeyCallback);
...
}

And GLWindow.cpp:

void GLWindow::setKeyCallback(const KeyCallback& callback)
{
    glfwSetKeyCallback(handle, ?????????);
}

Just in case, I provide the complete program code:

Window.h:

#include <glad/glad.h>
#include <glfw\glfw3.h>
#include <functional>
#include <string>
#include <iostream>

enum class Modifier
{
    NoModifier = 0,
    Shift = 1,
    Control = 2,
    Alt = 4,
    Super = 8,
};
enum class Action
{
    Release = 0,
    Press = 1,
    Repeat = 2,
};
enum class ButtonCode
{
    Button_0 = 0,
    //... repeats all buttons codes from the glfw header
};
enum class KeyCode
{
    UNKNOWN = -1,
    Space = 32,
    //.... repeats all key codes from the glfw header
};
class GLWindow
{
public:
    using KeyCallback = std::function<void(GLFWwindow* window, int key, int scancode, int action, int mode)>;
    using CursorPosCallback = std::function<void(double, double)>;
    using MouseCallback = std::function<void(ButtonCode, Action, Modifier, double, double)>;
    using ScrollCallback = std::function<void(double, double)>;
    GLWindow(const std::string& title, uint32_t width, uint32_t height);
    ~GLWindow();
    uint32_t getWidth() const;
    uint32_t getHeight() const;
    void setKeyCallback(const KeyCallback& callback);
    void setCursorPosCallback(const CursorPosCallback& callback);
    void setMouseCallback(const MouseCallback& callback);
    void setScrollCallback(const ScrollCallback& callback);
    GLFWwindow* getGLFWHandle() const;
private:
    GLFWwindow* handle;
    // TODO
};

Window.cpp:

#include <glfw\glfw3.h>
#include "GLWindow.h"


GLWindow::GLWindow(const std::string& title, uint32_t width, uint32_t height)
{
    handle = glfwCreateWindow(width, height, title.data(), nullptr, nullptr);
    glfwMakeContextCurrent(handle);
    static bool initGLAD = false;
    if (!initGLAD)
    {
        initGLAD = true;
        gladLoadGLLoader((GLADloadproc)glfwGetProcAddress);
    }
    glfwSetWindowUserPointer(handle, this);
    glfwSetKeyCallback(handle,/* implementation details */);
    glfwSetMouseButtonCallback(handle, /* implementation details */);
    glfwSetCursorPosCallback(handle, /* implementation details */);
    glfwSetScrollCallback(handle, /* implementation details */);
}

GLWindow::~GLWindow()
{

}

uint32_t GLWindow::getWidth() const
{
    return uint32_t();
}

uint32_t GLWindow::getHeight() const
{
    return uint32_t();
}

void GLWindow::setKeyCallback(const KeyCallback& callback)
{
    glfwSetKeyCallback(handle, ?????????);
}

void GLWindow::setCursorPosCallback(const CursorPosCallback& callback)
{

}

void GLWindow::setMouseCallback(const MouseCallback& callback)
{

}

void GLWindow::setScrollCallback(const ScrollCallback& callback)
{

}

GLFWwindow* GLWindow::getGLFWHandle() const
{
    return nullptr;
}

Main.cpp:

#include <glfw\glfw3.h>
#include "GLWindow.h"

void onKeyCallback(KeyCode key, Action action, Modifier mods)
{
    std::cout << "Key: " << glfwGetKeyName(key, 0) << " is pressed." << std::endl;
}

int main()
{
    glfwInit();
    GLWindow window("myWindow", 640, 480);
    window.setKeyCallback(onKeyCallback);

    while (glfwWindowShouldClose(window.getGLFWHandle())
    {
        glfwSwapBuffers(window.getGLFWHandle());
        glfwWaitEvents();
    }
    glfwTerminate();
    return 0;
}
genpfault
  • 51,148
  • 11
  • 85
  • 139
  • You can't, you have to use [lambda functions](https://de.cppreference.com/w/cpp/language/lambda). See [glfwSetCursorPosCallback to function in another class](https://stackoverflow.com/questions/29356783/glfwsetcursorposcallback-to-function-in-another-class/59633789) – Rabbid76 Jul 19 '20 at 12:41
  • 2
    Write a wrapper function, that takes the paramters required by GLFW, casts them to your custom types and calls the actual handler? – Lukas-T Jul 19 '20 at 12:47
  • How can i write this wrapper function? I also thought about this, but due to lack of knowledge about OpenGL, I do not know how to do it. – Stepan_Radchenko Jul 19 '20 at 16:40
  • Rabbid76 posted a link that explains what you need to do to connect the callback to your class. That's your wrapper function. Instead of calling some member function, you call the appropriate std::function (store those functions as members). Casting the parameters should be simple then. – Lukas-T Jul 19 '20 at 16:55

0 Answers0