OpenTK — после умножения с помощью ProjectionMatrix больше ничего не отображается

Из учебника, который отказался объяснить это, я получил следующий код. Это был учебник lwjgl, который я скопировал, и он прекрасно работал. Я не уверен, что проблема создается тем, что OpenGl отличается от java openGl, но, поскольку это всего лишь математика, я был бы удивлен этим:

private void createProjectionMatrix(int width, int height)
{
    float aspectRatio = width / height;
    float yScale = (float)((1f / Math.Tan(Maths.degreeToRadian(FOV/2f))) * aspectRatio);
    float xScale = yScale / aspectRatio;
    float frustumLength = FAR_PLANE - NEAR_PLANE;

    projectionMatrix = new Matrix4();
    projectionMatrix.M11 = xScale;
    projectionMatrix.M22 = yScale;
    projectionMatrix.M33 = -((FAR_PLANE + NEAR_PLANE) / frustumLength);
    projectionMatrix.M34 = -1;
    projectionMatrix.M43 = -((2 * NEAR_PLANE * FAR_PLANE) / frustumLength);
    projectionMatrix.M44 = 0;   
}

Это я умножил на матрицу преобразования (которая сработала). Я передаю матрицу в шейдер, выполняя uniformLocation_projectionMatrix = GL.GetUniformLocation(programID, "projectionMatrix"), а затем GL.UniformMatrix4(uniformLocation_projectionMatrix, false, ref projectionMatrix) таким образом, я также получил матрицу трансформации, так что это не должно быть проблемой.
В шейдере я делаю gl_Position = projectionMatrix * transformationMatrix * vec4(in_position, 1.0) (опять же, без проекцииMatrix все работает нормально ), а до этого uniform mat4 projectionMatrix; (как вы можете подтвердить, я написал это точно так же).
Я не уверен, какая дальнейшая часть кода вам нужна, поэтому не стесняйтесь спрашивать, спасибо.
Редактировать 1 : я попытался транспонировать его (установив false на true), результат был таким же

Редактировать 2:
Матрица, созданная кодом выше:
(1,428148; 0; 0; 0) ( 0; 2,53893; 0; 0) ( 0; 0; -1,002002; -1) ( 0; 0; -0,2002002; 0)

Матрица, созданная Matrix4.CreatePerspectiveFieldOfView():
(0,8033332; 0; 0; 0) ( 0; 1,428148; 0; 0) ( 0; 0; -1,002002; -1) ( 0; 0; -0,2002002; 0)
Матрица, созданная макетом из ответа Дрейкуна Д.:
(-0,00015625; 0; 0; 0) ( 0; 0,0002777778; 0; 0) ( 0; 0; -1,002002; -0,2002002) ( 0; 0; -1; 0)

Теперь я убедился, что проблема в другом - не работают все три матрицы.

Редактировать 3 - Больше кода: пока это мой вершинный шейдер.

#version 440 core

layout (location = 0) in vec3 in_position;
layout (location = 1) in vec2 in_textureCoordinates;

uniform mat4 translation;
uniform mat4 rotationX;
uniform mat4 rotationY;
uniform mat4 rotationZ;
uniform mat4 scale;

uniform mat4 projectionMatrix;

out vec2 textureCoordinates;

void main(void)
{
    mat4 transformationMatrix = translation * rotationX * rotationY * rotationZ * scale;
    gl_Position = projectionMatrix * transformationMatrix * vec4(in_position,  1.0);
    textureCoordinates = in_textureCoordinates;
}

А это функция рендеринга:

public void render(Entity entity, ShaderProgram shader)
    {
        TexturedModel texturedModel = entity.Model;
        RawModel model = texturedModel.Model;
        GL.BindVertexArray(model.VaoID);
        GL.EnableVertexAttribArray(0);
        GL.EnableVertexAttribArray(1);
        shader.loadTransformationMatrix(
            entity.Position, entity.RotX, entity.RotY, entity.RotZ, entity.Scale);
        GL.ActiveTexture(TextureUnit.Texture0);
        GL.BindTexture(TextureTarget.Texture2D, texturedModel.Texture.ID);
        GL.DrawElements(BeginMode.Triangles, model.VertexCount, DrawElementsType.UnsignedInt, 0);
        GL.DisableVertexAttribArray(0);
        GL.DisableVertexAttribArray(1);
        GL.BindVertexArray(0);
    }    

и конструктор рендерера загружает проекционную матрицу:

public Renderer(int width, int height, ShaderProgram shader)
    {
        createProjectionMatrix(width, height);
        shader.loadProjectionMatrix(projectionMatrix);
    }

person harlekintiger    schedule 28.07.2017    source источник
comment
Многие другие вещи могут быть неправильными. Пожалуйста, предоставьте mcve   -  person Ripi2    schedule 28.07.2017
comment
За последнюю неделю я тщательно собрал это вместе, я не думаю, что достаточно хорош, чтобы извлечь что-либо. Код, который я предоставил, - это единственное, что я изменил, и до этого он работал... У меня такое чувство, что проблема как-то связана с буферизацией глубины или какой-то другой вещью, связанной с глубиной.   -  person harlekintiger    schedule 28.07.2017
comment
как я вообще должен это делать в программе opengl? Есть шейдер, загрузчик шейдеров, рендерер, gameLoop, набор математических инструментов и класс сущностей, предоставляющий что-то для рендеринга — все это жизненно важно, не так ли?   -  person harlekintiger    schedule 28.07.2017
comment
прежде чем я потрачу хотя бы дюжину часов на создание mcve, не могли бы вы проверить, правильно ли настроена матрица перспективной проекции?   -  person harlekintiger    schedule 28.07.2017
comment
сделайте m33 и m43 положительными, убедитесь, что ваши плоскости действительно охватывают ваш контент, убедитесь, что матрица правильно передана в шейдер.   -  person LJᛃ    schedule 28.07.2017
comment
Ваш aspectRatio неверен, потому что вы делите int на int. Вы должны привести одно из этих значений к float.   -  person SurvivalMachine    schedule 28.07.2017
comment
это говорит мне, что актерский состав лишний. Я добавил много скобок, но это все еще не решает проблему float aspectRatio = (float)(width) / ((float)(height)); Я также пытался сделать m33 и m43 положительными (обе идеи во всех возможных комбинациях). Я также не понимаю, почему плоскость не должна охватывать два моих треугольника.   -  person harlekintiger    schedule 28.07.2017
comment
Вы можете сравнить свою перспективную матрицу с OpenTK CreatePerspectiveFieldOfView, если они то же ваша проблема живет в другом месте.   -  person Ripi2    schedule 28.07.2017
comment
Я сделал, спасибо. Они не одинаковы, но оба они не работают. Правилен ли мой метод загрузки? Я нашел некоторые источники, в которых говорится, что он должен быть загружен через GL.MatrixMode(MatrixMode.Projection) GL.LoadMatrix(ref projectionMatrix); - хотя я не уверен, как шейдер узнает, что я это сделал. Также у меня есть GL.Enable(EnableCap.DepthTest) и GL.DepthFunc(DepthFunction.Lequal) в onLoad, а также GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit) в цикле - на всякий случай это важно знать   -  person harlekintiger    schedule 28.07.2017
comment
Правильная матрица находится здесь. Вы обменяли xScale и yScale при работе с aspectRatio.   -  person Ripi2    schedule 28.07.2017
comment
Другая матрица (трансформация, как вы говорите) важна. Важно то, как вы проходите и читаете его в шейдерах. Если вы проходите вершины в порядке или в обратном важно. Многое имеет значение. Вот почему я прошу полный пример.   -  person Ripi2    schedule 28.07.2017
comment
Я добавил больше деталей в вопрос. Что значит я поменял xScale и yScale? Должен ли я поменять их местами?   -  person harlekintiger    schedule 28.07.2017
comment
Правильный код: float yScale = (float)(1f / Math.Tan(Maths.degreeToRadian(FOV/2f)));   -  person Ripi2    schedule 28.07.2017
comment
Мне не нужно умножать его на aspectRatio? Интересно. Хотя, к сожалению, это все еще не решает проблему. Верен ли порядок, в котором я умножаю матрицы?   -  person harlekintiger    schedule 28.07.2017
comment
Это мой последний комментарий. Кажется, что все ваши матрицы преобразования позиционируют треугольник(и) в мире. Я не вижу преобразования вида, если ваша камера не находится в (0,0,0) и смотрит в сторону (0,0,-1). Добавьте lookAt-матрицу   -  person Ripi2    schedule 28.07.2017
comment
Матрица vew, которую я собирался внедрить после этой проекции, работает - шаг за шагом (я обнаружил, что реализация сразу многих делает неоправданно трудным поиск ошибки/ошибки, если она возникает). В прошлый раз, когда я все это делал (тогда еще в lwjgl), все работало идеально, и порядок тоже был в порядке. Да, «камера» по-прежнему находится в положении 0,0,0, и, как я уже сказал, без проекционной матрицы треугольники отображаются нормально, вращаются, как мне заблагорассудится, и т. д. и т. д. Единственное, что я не могу сделать, это сильно их переместить. направление z (положительное или отрицательное), поэтому мне нужна проекцияMatrix. х и у работают нормально   -  person harlekintiger    schedule 28.07.2017
comment
Давайте продолжим обсуждение в чате.   -  person harlekintiger    schedule 28.07.2017


Ответы (2)


если вы хотите попробовать другой метод построения этой проекционной матрицы, вы можете попробовать этот с математикой объяснение

введите здесь описание изображения

не должно быть слишком жестким,

r и l обозначают правое и левое и должны быть чем-то вроде -width/2, width2

b и t обозначают низ и право, -высота/2, высота/2

n и f обозначают ближнюю и дальнюю плоскости, попробуйте разные значения, просто проверьте, что ваш z принадлежит интервалу, удачи. Я не уверен, но посмотрите на схему, чтобы увидеть знак ближней и дальней плоскости.

person Paltoquet    schedule 28.07.2017
comment
Я попробовал эту матрицу, и программа все еще не работает. Я поставил результаты в вопросе выше. Есть ли у вас какие-либо идеи, где загрузка могла пойти не так? Или лучше так сказать, в чем еще может быть проблема? Я все еще думаю, что это как-то связано с тестом на глубину или что-то в этом роде. - person harlekintiger; 28.07.2017
comment
@harlekintiger, каков диапазон координаты z ваших вершин? - person Paltoquet; 28.07.2017
comment
Для матрицы я использовал NEAR_PLANE = 0.1f и FAR_PLANE = 100. Я визуализирую три «вещи» (сущности, в основном два треугольника, отображающие текстуру). Один в 0, 0, 0, второй в 0, 0, 80 и третий в 0, 0, -80. Мои мысли были такими: хотя бы один из них должен быть виден - person harlekintiger; 28.07.2017
comment
немного странно, что у вас есть значение ‹0 в M11, а ваш NEAR_PLANE положительный - person Paltoquet; 28.07.2017
comment
Предоставленные мной vec3 — это смещения трансформации для transformMatrix. Сами вершины -0.5f, 0.5f, 0f, -0.5f, -0.5f, 0f, 0.5f, -0.5f, 0f, 0.5f, 0.5f, 0f и индексы 0,1,3, 3,1,2 - person harlekintiger; 28.07.2017
comment
(2*n)/(r-l) = (2 * 0.1f) / (-(width/2.0f) - (width/2.0f)) = 0.2f / (-(1280/2) - (640)) = 0.2f / -1280 = -0.00015625 Я сделал расчет вручную, наверное, я ошибся, как рассчитать r и l ? - person harlekintiger; 28.07.2017

Прежде всего, прежде чем делать что-либо еще, проверьте, вызываете ли вы GL.UseProgram(shaderProgram) напрямую после создания программы, чтобы избежать ошибок, таких как попытка загрузить матрицу проекции без использования GL с помощью шейдера.
Спасибо всем за помощь, хоть чему-то научился

person harlekintiger    schedule 28.07.2017
comment
Если бы вы предоставили полный пример, возможно, кто-то нашел бы эту ошибку вместо того, чтобы сосредотачивать так много комментариев в определении матрицы. Пожалуйста, научитесь составлять вопросы. - person Ripi2; 29.07.2017