Из учебника, который отказался объяснить это, я получил следующий код. Это был учебник 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);
}
aspectRatio
неверен, потому что вы делитеint
наint
. Вы должны привести одно из этих значений кfloat
. - person SurvivalMachine   schedule 28.07.2017float aspectRatio = (float)(width) / ((float)(height));
Я также пытался сделать m33 и m43 положительными (обе идеи во всех возможных комбинациях). Я также не понимаю, почему плоскость не должна охватывать два моих треугольника. - person harlekintiger   schedule 28.07.2017GL.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.2017xScale
иyScale
при работе сaspectRatio
. - person Ripi2   schedule 28.07.2017float yScale = (float)(1f / Math.Tan(Maths.degreeToRadian(FOV/2f)));
- person Ripi2   schedule 28.07.2017