Круг вытянут при рендеринге в OpenGL ES 2 - PullRequest
1 голос
/ 13 февраля 2020

На моем устройстве нарисован простой белый кружок, но он пропорционально растягивает его по моему устройству в зависимости от размеров экрана. Обыскивая 2D-примеры и возможные ответы, я не смог правильно их масштабировать.

Мой класс рендеринга:

@Override
public void onSurfaceChanged(GL10 gl, int width, int height)
{
    float scaleX = (float) width / Screen.getScreenWidthPx();
    float scaleY = (float) height / Screen.getScreenHeightPx();
    final int vpWidth = (int)(Screen.getScreenWidthPx() * scaleX);
    final int vpHeight = (int)(Screen.getScreenHeightPx() * scaleY);

    GLES20.glViewport(0, 0, vpWidth, vpHeight);

    mCam.setProjection(Screen.getScreenWidthPx(), Screen.getScreenHeightPx());
}

Мой класс камеры:

public void setProjection(float width, float height)
{        
    final float ratio = width / height;
    Matrix.orthoM(mProjection, 0, 0, width, height, 0, -1, 1);
}

Вершинный шейдер:

private String mVSCode =
        "attribute vec4 vPosition;" +
                "uniform float sWidth;" +
                "uniform float sHeight;" +
                "void main() {" +
                "gl_Position = vPosition;" +                  
                "}";

Результат:

enter image description here

1 Ответ

1 голос
/ 13 февраля 2020

Вы должны решить, что вы хотите сделать. Если вы хотите нарисовать координаты вершины 1: 1 в координатах окна (в пикселях), ваша проекция orthographi c верна.
Но если вы просто хотите позаботиться о соотношении сторон, то проекция должна быть :

public void setProjection(float width, float height)
{        
    final float ratio = width / height;
    Matrix.orthoM(mProjection, 0, -1, 1, 1/ratio, -1/ratio, -1, 1);
}

В любом случае вам необходимо преобразовать координату вершины с помощью проекционной матрицы orthographi c в вершинном шейдере.

Добавить матричную униформу (mat4 uProjection) в вершинный шейдер. Установите форму на mProjection. Умножьте координату вершины на uProjection в вершинном шейдере:

attribute vec4 vPosition;

uniform uProjection;

void main() {
    gl_Position = uProjection* vPosition;
}

В качестве альтернативы вы можете вручную установить ортогональную c матрицу проекции в вершинном шейдере:
(Конечно, у вас есть установить униформу sWidth соответственно sHeight)

attribute vec4 vPosition;

uniform float sWidth;
uniform float sHeight;

void main() {

    mat4 projection = mat4(1.0);
    projection[1][1] = -sHeight/sWidth;

    gl_Position = projection * vPosition;            
};

Или, если вы хотите использовать координаты окна:

attribute vec4 vPosition;

uniform float sWidth;
uniform float sHeight;

void main() {

    mat4 projection = mat4(
        vec4( 2.0/sWidth,  0.0,         0.0, 0.0),
        vec4( 0.0,        -2.0/sHeight, 0.0, 0.0),
        vec4( 0.0,         0.0,         1.0, 0.0),
        vec4(-1.0,         1.0,         0.0, 1.0));

    gl_Position = projection * vPosition;            
};
...