Вершины треугольника в неправильном месте с матрицей ортогональной проекции GLM - PullRequest
1 голос
/ 26 марта 2019

В последнее время я пытаюсь визуализировать треугольник (как на рисунке 1) в моем представлении содержимого окна (OSX NSView) с использованием OpenGL, я делаю «Ортогональную проекцию» с функцией библиотеки GLM glm :: ortho, после рендеринга вершин все треугольники находятся не в том месте, они, кажется, имеют смещение по отношению к представлению содержимого окна.

У меня есть 2 вопроса:

  1. Я неправильно понял, что такое glm :: ortho (основать следующий код)?

  2. Когда размер окна изменяется (Zoom In, Zoom Out), Как сохранить треугольник на том же месте в окне (т. Е. Верхняя вершина в середине ширины и нижние вершины в углу)

Результат является следующим:

enter image description here

Моя функция рендеринга:

- (void)render
{
    float view_width = self.frame.size.width;
    float view_height = self.frame.size.height;

    glViewport(0, 0, view_width, view_height);
    glClearColor(0.0, 0.0, 0.0, 1.0);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    // Using Orthographic Projection Matrix, vertex position
    // using view coordinate(pixel coordinate)
    float positions[] = {
        0.0f,                    0.0f,           0.0f, 1.0f,
        view_width,              0.0f,           0.0f, 1.0f,
        view_width/(float)2.0,   view_height,    0.0f, 1.0f,
    };

    glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(positions), positions);

    glm::mat4 p = glm::ortho(0.0f, view_width, 0.0f, view_height);
    glm::mat4 v = glm::lookAt(glm::vec3(0, 0, 1),  glm::vec3(0, 0, 0),  glm::vec3(0, 1, 0));
    glm::mat4 m = glm::mat4(1.0f);

    // upload uniforms to shader
    glUniformMatrix4fv(_projectionUniform, 1, GL_FALSE, &p[0][0]);
    glUniformMatrix4fv(_viewUniform, 1, GL_FALSE, &v[0][0]);
    glUniformMatrix4fv(_modelUniform, 1, GL_FALSE, &m[0][0]);

    glDrawElements(GL_TRIANGLE_STRIP, sizeof(positions) / sizeof(positions[0]),GL_UNSIGNED_SHORT, 0);

    [_openGLContext flushBuffer];
}

мой вершинный шейдер:

#version 410

in vec4 position;
uniform highp mat4 projection;
uniform highp mat4 view;
uniform highp mat4 model;

void main (void)
{
    gl_Position = position * projection * view * model;
}

Ответы [ 2 ]

1 голос
/ 26 марта 2019
Матрица

A glm инициализируется так же, как матрица GLSL. Для получения дополнительной информации см. Язык затенения OpenGL 4.6, 5.4.2 Векторные и матричные конструкторы, стр. 101 .

Вектор нужно умножить на матрицу справа.

См. Программирование GLSL / Векторные и матричные операции :

Обратите внимание, что вектор нужно умножить на матрицу справа.

Если вектор умножается на матрицу слева, результат соответствует умножению вектора строки слева на матрицу. Это соответствует умножению вектора столбца на транспонированную матрицу справа.

Это означает, что вы должны изменить вершинное преобразование в вершинном шейдере:

gl_Position = position * projection * view * model;

gl_Position = projection * view * model * position;
0 голосов
/ 26 марта 2019

@ Rabbid76 ответил на мой первый вопрос, все работает! Большое спасибо. Второй вопрос, в OSX, при изменении размера окна (содержащего представление OpenGL), NSOpenGLContext должен быть обновлен, например:

- (void)setFrameSize:(NSSize)newSize {
    [super setFrameSize:newSize];
    // update the _openGLContext object
    [_openGLContext update];
    // reset viewport
    glViewport(0, 0, newSize.width*2, newSize.height*2);
    // render
    [self render];
}
...