Рисование квадрата на прямоугольном окне в opengl - PullRequest
2 голосов
/ 15 июня 2019

Я рисую 3D-куб в LWJGL 3. Он хорошо отрисовывается с размером окна 600 * 480. Это идеальный куб.

Но если я увеличу ширину окна до 900, а высота останетсятот же самый.Куб имеет прямоугольную форму.

В разрешении 640 * 480 передняя грань куба:

В 900 * 480разрешение передней грани куба:

Я хочу сделать идеальный квадрат без прямоугольника.

если требуетсяЦикл рендеринга выглядит следующим образом:

private void loop() {

GL.createCapabilities();

        // Set the clear color
        glClearColor(0f, 0.0f, 0.0f, 0.0f);

        float x = 0.5f;
        float y = 0.5f;
        float z = 0.5f;
        float[] vertices = new float[] {
                // VO
                -x, y, z,
                // V1
                -x, -y, z,
                // V2
                x, -y, z,
                // V3
                x, y, z,
                // V4
                -x, y, -z,
                // V5
                x, y, -z,
                // V6
                -x, -y, -z,
                // V7
                x, -y, -z, };

        float[] colours = new float[] {
               0.5f, 0.0f, 0.0f,
              0.0f, 0.5f, 0.0f, 
             0.0f, 0.0f, 0.5f, 
             0.0f, 0.5f, 0.5f,
              0.5f,0.0f, 0.0f, 
             0.0f, 0.5f, 0.0f,
              0.0f, 0.0f, 0.5f,
              0.0f, 0.5f, 0.5f, };

        int[] indices = new int[] {
                // Front face
                0, 1, 3, 3, 1, 2,
                // Top Face
                4, 0, 3, 5, 4, 3,
                // Right face
                3, 2, 7, 5, 3, 7,
                // Left face
                6, 1, 0, 6, 0, 4,
                // Bottom face
                2, 1, 6, 2, 6, 7,
                // Back face
                7, 6, 4, 7, 4, 5, };

        RawModel model = Loader.loadRawModel(vertices, indices, colours);
        ShaderProgram shader = null;

        Transformation transformation = new Transformation();

        try {

            shader = new ShaderProgram(Utils.loadTextFile("src/shaders/vertexShader.txt"),
                    Utils.loadTextFile("src/shaders/fragmentShader.txt"));
            shader.link();
            shader.createUniform("projectionMatrix");
            shader.createUniform("worldMatrix");
        } catch (Exception e) {
            e.printStackTrace();
        }

        float rotation = 0;


        while (!glfwWindowShouldClose(window)) {
            glEnable(GL11.GL_DEPTH_TEST);
            glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 

            shader.bind();

            shader.setUniform("projectionMatrix", transformation.getProjectionMatrix((float) Math.toRadians(60),
                    (float) (width / height), 0.1f, 1000f));
            shader.setUniform("worldMatrix", transformation.getWorldMatrix(new Vector3f(0, 0, -3f),
                    new Vector3f(rotation, rotation, rotation), 1));
            model.render();

            shader.unBind();

            glfwSwapBuffers(window); 
            glfwPollEvents();
        }

        shader.dispose();
        Loader.dispose();
    }

Ответы [ 2 ]

1 голос
/ 15 июня 2019

Благодаря @Derhass проблема теперь решена. Проблема заключалась в том, что я вычислил соотношение сторон как:

float aspectRatio = (float)(900/480);

, что равно 1.0f .

Но когда я добавил f к ширине и высоте:

float aspectRatio = (float)(900f/480f);

Это дало право aspectRatio из 1.875 .

теперь куб выглядит как квадрат.

the cube image now :

0 голосов
/ 15 июня 2019

Это результат работы NDC (нормализованных координат устройства). Они не принимают во внимание пропорции окна. Я считаю, что проблема в том, что вы не обновляете значения width и height, когда размеры окна изменяются. Все, что вам нужно сделать, это написать обратный вызов изменения размера кадрового буфера и установить его с помощью glfwSetFramebufferSizeCallback():

glfwSetFramebufferSizeCallback(window, (window, newWidth, newHeight) -> {
        width = newWidth;
        height = newHeight;
    });

Это может решить проблему. Просто не забудьте поставить его перед циклом рендеринга.

...