Масштабирование четырехугольника некорректно после изменения размера окна.Как исправить? - PullRequest
0 голосов
/ 02 февраля 2019

Если я пытаюсь сделать квадрат с одинаковым масштабированием для x и y без изменения размера окна, все в порядке.Но после изменения размера окна больше не отображается квадрат.Вместо этого вы можете видеть прямоугольник, хотя я пересчитываю матрицу проекции и передаю матрицу шейдеру каждый раз, когда изменяется ширина или высота окна.С другой шириной и высотой масштабирование квадрата неверно.Изменение размера окна в моем коде без изменения размера окна не меняет масштабирование.

Понятия не имею, где ошибка.Возможно, я что-то пропустил.

Координаты:

float[] positions = new float[] {0, 1, 0, 0, 1, 1, 1, 0};

Расчет матрицы проекции:

 public static void createProjectionMatrix() {

    Vector2f windowSize = DisplayManager.getWindowSize();

    float aspectRatio = windowSize.x / windowSize.y;
    float halfWidth = 1.0f;
    float halfHeight = halfWidth / aspectRatio;

    float left = -halfWidth;
    float right = halfWidth;
    float bottom = -halfHeight;
    float top = halfHeight;
    float far = -1f;
    float near = 1f;

    Matrix4f matrix = new Matrix4f();

    matrix.setIdentity();

    matrix.m00 = 2f / (right - left);
    matrix.m11 = 2f / (top - bottom);
    matrix.m22 = -2f / (far - near);
    matrix.m32 = (far + near) / (far - near);
    matrix.m30 = (right + left) / (right - left);
    matrix.m31 = (top + bottom) / (top - bottom);

    projectionMatrix = matrix;
 }

Расчет преобразования (Vector2f worldScale не используется):

private Vector2f getDisplayCoords(Vector2f percentage) {
    Vector2f v = DisplayManager.getWindowSize();
    return new Vector2f(v.x * percentage.x, v.y * percentage.y);    
}

public void loadTransformationMatricies() { 
    Vector2f displaySize = getDisplayCoords(size);
    Vector2f displayPos = getDisplayCoords(position);
    Vector2f display = DisplayManager.getWindowSize();

    Vector2f worldPos = Mouse.getWorldPos(displayPos);
    Vector2f worldScale = new Vector2f(displaySize.x / (display.x / 2.0f), displaySize.y / (display.y / 2));

    float x, y;
    x = worldPos.x;
    y = worldPos.y - CORNER_SCALE;
    //y is calculated correct. Moving the mouse to the same y value as calculated shows that everything is correctly calculated
    System.out.println(y + " | " + Mouse.getWorldPos().y);
    transforms[0] = Maths.getTransformationMatrix(new Vector2f(x, y), new Vector2f(CORNER_SCALE, CORNER_SCALE));
}

Проверьте размер:

GLFW.glfwSetWindowSizeCallback(WINDOW, new GLFWWindowSizeCallback() {

        @Override
        public void invoke(long arg0, int arg1, int arg2) {
            resized = true;
        }
});

Рендеринг (обычно отображает больше объектов):

@Override
protected void render() {
    shader.start();
    if(DisplayManager.isResized()) {
        shader.loadProjectionMatrix(MasterRenderer.getProjectionMatrix());
    }
    bindModel(Loader.getQuad(), new int[] {0});
    for(GUI gui : guis) {
        if(DisplayManager.isResized()) {
            gui.loadTransformationMatricies();
        }
        bindTexture(gui.getTexture().getTopLeftCorner(), GL13.GL_TEXTURE0);
        Matrix4f[] transforms = gui.getTransformations();
        for(int i = 0; i < 1; i++) {
            shader.loadTransformationMatrix(transforms[i]);
            drawSTRIP(Loader.getQuad());
        }
    }
    unbind(new int[] {0});
    shader.stop();
}

Vertexshader:

#version 400 core

in vec2 position;

uniform mat4 transformationMatrix;
uniform mat4 projectionMatrix;

out vec2 textureCoords;

void main (void){

    gl_Position =  projectionMatrix * transformationMatrix * vec4(position, 0, 1.0);
    textureCoords = vec2((position.x+1.0)/2.0, 1 - (position.y+1.0)/2.0);
}

Вы можете найтивесь код на Github, если вам нужно больше информации, но я только хочу знать, как решить эту конкретную проблему.https://github.com/StackOverflowEx/GameEngine2D

1 Ответ

0 голосов
/ 02 февраля 2019

После того, как размер окна изменился, прямоугольник области просмотра должен быть отрегулирован до нового размера:

Используйте glViewport для установки прямоугольника области просмотра.

Добавить метод updateViewPort в класс DisplayManager

public static void updateViewPort() {
    IntBuffer pWidth = stack.mallocInt(1);
    IntBuffer pHeight = stack.mallocInt(1);

    GLFW.glfwGetFramebufferSize(WINDOW, pWidth, pHeight);
    GL11.glViewport(0, 0, pWidth.get(0), pHeight.get(0)); 
}

Вызвать DisplayManager.updateViewPort в методе prepare в классе MasterRenderer:

private void prepare() {

    if(DisplayManager.isResized()) {
        DisplayManager.updateViewPort();
        createProjectionMatrix();
    }
    Camera.calcViewMatrix();

    GL11.glClear(GL11.GL_COLOR_BUFFER_BIT);
    GL11.glClearColor(1, 0, 0, 1);
}

См. Также Примеры кода Java для org.lwjgl.glfw.GLFW.glfwGetFramebufferSize () .

...