OpenGL 转换无法按预期在 z 轴上工作

OpenGL Transformation doesn't work on z-axis as expected

本文关键字:工作 转换 OpenGL      更新时间:2023-10-16

我正在编写一个游戏引擎,但在 z 轴上的转换时遇到问题。当我在 z 轴上平移超过 1 个单位时,对象消失了。小于 1 的值对它保持在同一位置的对象没有影响。所有其他转换似乎都可以正常工作。

主循环的一部分:

while (unprocessedTime > frameTime) {
    rendering = true;
    unprocessedTime -= frameTime;
    if (window.isClosed()) {
        stop();
    }
    Time::setDelta(frameTime);
    game.update();
    if (frameCounter >= Time::SECOND) {
        std::cout << fps << std::endl;
        fps = 0;
        frameCounter = 0;
    }
}
if (rendering) {
    render();
    fps++;
}

渲染方法:

void MainController::render() {
    window.clear();
    game.render();
    window.update();
}

游戏更新和渲染方法:

void Game::update() {
    tmp += Time::getDelta();
    float sinTemp = sin(tmp);
    transform.setPos(glm::vec3(0, 0, sinTemp));
}
void Game::render() {
    shader.bind();
    shader.setUniform("transform", transform.getTransformation());
    mesh.draw();
}

着色器集统一方法:

void Shader::setUniform(std::string uniformName, glm::mat4 value) {
    glUniformMatrix4fv(uniforms[uniformName], 1, GL_FALSE, &value[0][0]);
}
转换

获取转换方法:

inline glm::mat4 getTransformation() const {
    glm::mat4 posMat = glm::translate(pos);
    glm::mat4 rotXMat = glm::rotate(rot.x, glm::vec3(1, 0, 0));
    glm::mat4 rotYMat = glm::rotate(rot.y, glm::vec3(0, 1, 0));
    glm::mat4 rotZMat = glm::rotate(rot.z, glm::vec3(0, 0, 1));
    glm::mat4 scaleMat = glm::scale(scale);
    glm::mat4 rotMat = rotZMat * rotYMat * rotXMat;
    return posMat * rotMat * scaleMat;
}

编辑顶点着色器:

#version 330
layout (location = 0) in vec3 position;
out vec4 color;
uniform mat4 transform;
void main() {
    color = vec4(clamp(position, 0.0, 1.0), 1.0);
    gl_Position = transform * vec4(position, 1.0);
}

您需要创建一个投影矩阵。这里有一个很好的解释它是什么,这里有一个关于如何构造一个的教程。

基本上,投影矩阵将 x 和 y 除以 z,因此较远的物体看起来更小。它还缩放 z,因此您可以看到的最远距离(远修剪平面)等效于 -1,您可以看到的最近距离等效于 1。不绘制立方体 (-1,-1,-1)、(1、1、1) 之外的所有内容。

如果没有投影矩阵,您的对象将无法正确显示深度,并且需要一些看似随机的比例才能在屏幕上可见。