Ортографическая матрица OpenGL не работает должным образом

Я создал простую 2D-область с использованием OpenGL, состоящую из плиток. Эти плитки по умолчанию растянуты относительно соотношения сторон экрана. Чтобы исправить это, я попытался использовать матрицу ортогональной проекции. Вот как я его создал:

public void createProjectionMatrix() {
    float left = 0;
    float right = DisplayManager.getScreenWidth();
    float top = 0;
    float bottom = DisplayManager.getScreenHeight();
    float near = 1;
    float far = -1;

    projectionMatrix.m00 = 2 / (r - l);
    projectionMatrix.m11 = 2 / (t - b);
    projectionMatrix.m22 = -2 / (f - n);
    projectionMatrix.m30 = - (r + l) / (r - l);
    projectionMatrix.m31 = - (t + b) / (t - b);
    projectionMatrix.m32 = - (f + n) / (f - n);
    projectionMatrix.m33 = 1;
}

Проблема, вероятно, в этом, но я просто не могу ее найти. Затем я вызываю этот метод с созданием моего средства визуализации, сохраняю его в универсальной переменной и использую в вершинном шейдере следующим образом:

vec4 worldPosition = transformationMatrix * vec4(position, 0, 1);
gl_Position = projectionMatrix * viewMatrix * worldPosition;

Где projectionMatrix - это mat4, который соответствует ранее созданной ортогональной матрице проекции.

Прямо сейчас абсолютно ничего, кроме четкой цветопередачи.

РЕДАКТИРОВАТЬ:

Матрица ортогональной проекции создается и загружается в шейдеры сразу после создания средства визуализации и после создания шейдера.

public Renderer() {
    createOrthoMatrix();
    terrainShader.start();
    terrainShader.loadProjectionMatrix(projectionMatrix);
    terrainShader.stop();
    GL11.glEnable(GL13.GL_MULTISAMPLE);
    GL11.glClearColor(0, 0, 0.5f, 1);
}

Остальные матрицы передаются при каждом рендеринге с помощью метода loadUniforms ().

for(Terrain t : batch) {
    loadUniforms(t, terrainManager, camera, lights);
    GL11.glDrawElements(GL11.GL_TRIANGLES, model.getModel().getVertexCount(), GL11.GL_UNSIGNED_INT, 0);
}

private void loadUniforms(Terrain t, TerrainManager tm, Camera camera, List<Light> lights) {
    Matrix4f matrix = Maths.createTransformationMatrix(t.getPosition(), 0, 0, 0, 1);
    terrainShader.loadTransformationMatrix(matrix);
    terrainShader.loadViewMatrix(camera);
    terrainShader.loadNumberOfRows(tm.getNumberOfRows());
    terrainShader.loadOffset(t.getOffset());
    terrainShader.loadLights(lights);
}

Наконец, вот как выглядит вершинный шейдер:

#version 400 core

in vec2 position;

uniform mat4 transformationMatrix;
uniform mat4 viewMatrix;
uniform mat4 projectionMatrix;

void main(void) {
vec4 worldPosition = transformationMatrix * vec4(position, 0, 1);
gl_Position = projectionMatrix * viewMatrix * worldPosition;
}

person Dylan Deshler    schedule 23.06.2015    source источник
comment
orthoMatrix.m00 = 2 / (r - 1)? Разве это не должно быть (r - l)? 1! = _ 4_.   -  person genpfault    schedule 23.06.2015
comment
@genpfault Спасибо, что указали на это! но проблема все еще существует   -  person Dylan Deshler    schedule 24.06.2015
comment
Пришло время MCVE.   -  person genpfault    schedule 24.06.2015
comment
Каков порядок элементов в вашей матричной структуре / классе?   -  person Reto Koradi    schedule 24.06.2015
comment
@RetoKoradi Не уверен, что вы имеете в виду, но в шейдере я начинаю с ортогональной матрицы * матрицы просмотра * матрицы преобразования * vec4 (position, 0, 1)   -  person Dylan Deshler    schedule 24.06.2015
comment
Я спрашивал о порядке элементов матрицы в определении структуры / класса. В каком порядке объявлены m00, m01, m10, m11 и т. Д.?   -  person Reto Koradi    schedule 24.06.2015
comment
@RetoKoradi Они пошли undefined, что, я думаю, ставит их в 0, не знаю, в каком порядке. Вы хотите, чтобы я определил все элементы в матрице? Я думаю, проблема связана с матрицей, устанавливаю ли я для всех элементов правильные значения? Правильно ли объявлены левый, верхний, правый, нижний, ближний и дальний?   -  person Dylan Deshler    schedule 24.06.2015
comment
Вероятно, они инициализированы по умолчанию. Но невозможно сказать, не зная, какой матричный класс вы используете. Вы что-то написали? Или вы используете какую-то стороннюю библиотеку?   -  person Reto Koradi    schedule 24.06.2015
comment
Если раньше он отображался нормально, то теперь размер рендеринга должен быть меньше пикселя. Попробуйте включить коэффициент масштабирования в матрицу (умножьте m00 и m11 на что-нибудь большое (например, 100), чтобы увидеть, так ли это). И вы можете переставить матрицу (поменять местами столбцы и строки). Вот почему @RetoKoradi захотел увидеть объявление матрицы.   -  person Nico Schertler    schedule 24.06.2015
comment
Ой, понял, это matrix4f из библиотеки lwjgl. Импортирую с org.lwjgl.util.vector.Matrix4f   -  person Dylan Deshler    schedule 24.06.2015
comment
@NicoSchertler Я сделал orthoMatrix.m00 = (2 / (right - left)) * 100 и orthoMatrix.m11 = (2 / (top - bottom)) * 100, но ничего не изменилось. Возможно, мне нужно переключить столбцы и строки. Не совсем уверен, как бы я это сделал, хотя   -  person Dylan Deshler    schedule 24.06.2015
comment
Просто переключите .m30 на .m03 и т. Д.   -  person Nico Schertler    schedule 24.06.2015
comment
@NicoSchertler Ничего не изменилось. Возможно ли, что моя камера находится за тем, что я пытаюсь визуализировать? Он инициализируется как Vector2f(1 , 1), поэтому z равен 0.   -  person Dylan Deshler    schedule 24.06.2015


Ответы (1)


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

Я изменил createProjectionMatrix (), чтобы он выглядел как

public void createProjectionMatrix() {
    float width = Display.getWidth();
    float height = Display.getHeight();
    float left = -width;
    float right = width * 1f;
    float top = height * 1f;
    float bottom = -height;
    float near = 0;
    float far = 10;

    projectionMatrix.m00 = (2f / (right - left)) * 1000;
    projectionMatrix.m11 = (2f / (top - bottom)) * 1000;
    projectionMatrix.m22 = 2f / (far - near);
    projectionMatrix.m30 = - (right + left) / (right - left);
    projectionMatrix.m31 = - (top + bottom) / (top - bottom);
    projectionMatrix.m32 = -(far + near) / (far - near);
    projectionMatrix.m33 = 1;
}

Умножение m00 и m11 на большое число - единственный способ увидеть что-либо, кроме четкого цвета. Если я правильно помню, это потому, что средство визуализации отображает меньше пикселя. Эту идею мне подарил @NicoSchertler. Так что большое вам спасибо! Шейдеры выглядят так же, и теперь все работает хорошо. Если у кого-то есть менее пиратское решение, поделитесь им, я буду рад увидеть, как оно было решено. Вот ссылка, которая мне очень помогла: OpenGL 3+ с орфографическим проекция направленного света.

person Dylan Deshler    schedule 28.06.2015