Здравствуйте, я следую руководству по opengl с этой страницы и пытаюсь реализовать класс камеры. Вот мой код класса камеры.
class Camera
{
public:
static float fov;
glm::vec3 pos;
glm::vec3 front;
glm::vec3 up;
bool firstMouse;
float screen_width;
float screen_height;
Camera(float screen_width, float screen_height);
~Camera();
void setup_scroll_inputs(GLFWwindow* window);
static void scroll_callback_static(GLFWwindow* window, double xoffset, double yoffset);
};
и ЦПП
void Camera::setup_scroll_inputs(GLFWwindow* window)
{
glfwSetScrollCallback(window, Camera::scroll_callback_static);
}
void Camera::scroll_callback_static(GLFWwindow* window, double xoffset, double yoffset)
{
fov -= (float)yoffset;
if (fov < 20.0f)
fov = 20.0f;
if (fov > 100.0f)
fov = 100.0f;
}
Чего я хочу добиться, так это функции увеличения и уменьшения масштаба всякий раз, когда я прокручиваю вверх или вниз.
Я попытался поместить функцию glfwSetScrollCallback
в функцию-член класса камеры, потому что
Я хочу, чтобы моя основная функция была максимально чистой.
Моя функция scroll_callback
должна быть статической функцией-членом, поскольку glfwSetScrollCallback
ожидает указатель на функцию.
Однако я хочу предоставить функции scroll_callback
возможность доступа к переменным-членам камеры.
Есть ли способ добиться этого?
На данный момент я сделал fov статической переменной-членом, поскольку в противном случае моя функция прокрутки не имела бы к ней доступа.
Статическая функция не сможет получить доступ к членам класса. Вы можете использовать лямбду без захвата для ее подключения.
Чтобы получить доступ к объекту камеры, вам нужно сохранить указатель на него, используя glfwSetWindowUserPointer
, и получить его внутри лямбды, используя glfwGetWindowUserPointer
glfwSetWindowUserPointer(window, &camera);
glfwSetScrollCallback(window, [](GLFWwindow* window,double xoffset, double yoffset) {
Camera* camera = (Camera*)glfwGetWindowUserPointer(window);
camera->scroll_callback(window, xoffset, yoffset);
});
glfwSetScrollCallback()
требуется указатель на функцию в стиле C, но захватывающая лямбда с ним несовместима.
Действительно, я поправил
Используйте glfwSetWindowUserPointer() , чтобы сохранить указатель Camera
объекта this
внутри объекта GLFWwindow
, а затем ваш обратный вызов может использовать glfwGetWindowUserPointer(), чтобы вернуть указатель.
void Camera::setup_scroll_inputs(GLFWwindow* window)
{
glfwSetWindowUserPointer(window, this);
glfwSetScrollCallback(window, Camera::scroll_callback_static);
}
void Camera::scroll_callback_static(GLFWwindow* window, double xoffset, double yoffset)
{
Camera *this = (Camera*) glfwGetWindowUserPointer(window);
...
}
Проверьте, поддерживает ли
GLFWwindow
хранение некоторых пользовательских данных. Если это так, вы можете сохранить в нем указательthis
, а затем использовать его в обратном вызове (выдержка из параметраwindow
) для вызова метода класса.