调整窗口大小后,四边形的缩放不正确。怎么修?

时间:2019-02-01 21:08:26

标签: java opengl glsl

如果我尝试渲染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();
}

顶点着色器:

#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 :(得分:0)

所述窗口的大小发生了变化后,将视口矩形已经被调整到新的大小:

使用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 Code Examples for org.lwjgl.glfw.GLFW.glfwGetFramebufferSize()