GLM正交投影矩阵在错误位置的三角形顶点

问题描述 投票:1回答:2

最近,我试图使用OpenGL在我的窗口内容视图(OSX NSView)中渲染一个三角形(如图1所示),我使用GLM库函数glm :: ortho进行“正交投影”,渲染后,三角形的顶点他们都在错误的地方,他们似乎偏向窗口内容视图。

我有两个问题:

  1. 我误解了glm :: ortho(基于以下代码)?
  2. 当窗口调整大小(放大,缩小)时,如何保持三角形在窗口中保持相同的位置(即宽度中间的顶部顶点和角落的底部顶点)?

结果如下:

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;
}
opengl glsl shader projection glm-math
2个回答
1
投票

glm矩阵以与GLSL矩阵相同的方式初始化。有关详细信息,请参阅The OpenGL Shading Language 4.6, 5.4.2 Vector and Matrix Constructors, page 101

向量必须乘以右边的矩阵。

GLSL Programming/Vector and Matrix Operations

请注意,向量必须乘以右边的矩阵。

如果向量与左侧的矩阵相乘,则结果对应于将行向量从左侧乘以矩阵。这对应于将列向量与右侧的转置矩阵相乘。

这意味着您需要更改顶点着色器中的顶点变换:

gl_Position = position * projection * view * model;

gl_Position = projection * view * model * position;

0
投票

@ 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];
}
© www.soinside.com 2019 - 2024. All rights reserved.