GLFW 3: Как получить дельту колеса прокрутки мыши с помощью ScrollCallback (LWJGL 3) - PullRequest
0 голосов
/ 03 мая 2020

Я следую этому руководству по разработке 3D-игр с LWJGL и OpenGL. И в серии, инструктор использует LWJGL 2, а я использую LWJGL 3 с GLFW. И в определенном разделе он использует входные реализации LWJGL, доступные только в LWJGL 2, поэтому я вынужден использовать систему обратного вызова GLFW. Мне удалось добавить функцию ввода для клавишного ввода, перемещения курсора и ввода с помощью мыши, но когда я попытался добавить обратный вызов прокрутки, мне показалось, что смещения возвращают только -1 и 1 для направлений прокрутки, а при добавлении (Третье лицо) камера переводилась вперед и назад на неопределенное время, и целью было при каждом движении прокрутки камера переводила вперед или назад на определенное расстояние. В действительности я ожидал получить значения дельты для каждого прокручиваемого движения. Раньше я возился, пытаясь понять, смогу ли я установить значения смещения для некоторого времени задержки, а затем установить их обратно на 0, но безрезультатно. Я пытался найти ответ, но не нашел ничего, связанного с моей проблемой. Я могу быть глупым, но вот код.

Класс обратного вызова MouseScroll:

import org.lwjgl.glfw.GLFWScrollCallback;

    public class MouseScroll extends GLFWScrollCallback {

        private static float XScroll;
        private static float YScroll;
        private static float DXScroll;
        private static float DYScroll;

        @Override
        public void invoke(long window, double xoffset, double yoffset) {
            XScroll = (float) xoffset;
            YScroll = (float) yoffset;
            // Don't know how to achieve this here
        }

        /* Returns raw offset values */
        public float getXScroll() {
            return XScroll;
        }

        public float getYScroll() {
            return YScroll;
        }

        /* Returns the rate of each scrolling movement */
        public float getDXScroll() {
            return DXScroll;
        }

        public float getDYScroll() {
            return DYScroll;
        }

    }

Метод получения YScroll в классе ввода:

public static float getMouseYScroll() {
    return mouseScroll.getYScroll(); // mouseScroll is reference to MouseScroll callback
}

Метод с использованием обратного вызова в камере. java:

private void calculateZoom() {
        float zoomLevel =  Input.getMouseYScroll() * 0.1f;
        distanceFromPlayer -= zoomLevel;
    }

Метод обновления в камере. java:

public void move() {
        calculateZoom();
        calculatePitch();
        calculateAngleAroundPlayer();
        float horizontalDistance = calculateHorizontalDistance();
        float verticalDistance = calculateVerticalDistance();
        calculateCameraPosition(horizontalDistance, verticalDistance);
        this.yaw = 180 - (player.getRotY() + angleAroundPlayer);
    } 

И, наконец, camera.move() вызывается при каждой итерации l oop

1 Ответ

0 голосов
/ 04 мая 2020

GLFWScrollCallback вызывается всякий раз, когда пользователь генерирует какую-либо операцию прокрутки (вверх или вниз или даже влево или вправо). В результате вы установите XScroll / YScroll на -1 или 1 и оставите его таковым до следующего события прокрутки. Вам нужно реализовать какой-то способ обнулить его. Потенциально вы можете сделать что-то вроде

    public float getYScroll() {
        float value = YScroll;
        YScroll = 0.0f;
        return value;
    }

, но это сработает только в том случае, если вы вызываете getYScroll только один раз за кадр. Не совсем ясно, как вы хотите обрабатывать такие события (т.е. хотите ли вы хранить их до тех пор, пока они не будут использованы - возможно, не каждый кадр), но, скорее всего, вам это удастся, просто добавив метод сброса к MouseScroll, который вы вызываете в конец каждого кадра - поскольку вы запрашиваете колесо прокрутки каждый кадр, никакое событие не будет потеряно.

...