旋转时,多维数据集不会按预期呈现

时间:2017-11-14 19:48:16

标签: c++ opengl matrix glm-math

我正在使用OpenGL在C ++中开发一个应用程序。我的问题是,当我将一个立方体渲染到具有旋转的屏幕时,它看起来不成比例(参见图像)。

我正在使用以下NuGet包:

Nuget Packages

当立方体旋转0度时:

cube at 0 degrees

当立方体旋转45度时:

cube at 45 degrees

当立方体旋转90度时:

cube at 90 degrees

当立方体旋转180度时:

cube at 180 degrees

当立方体旋转360度时:

cube at 360 degrees isn't even visible

以下代码是计算矩阵的地方:

glm::mat4 DrawnEntity::getMatrix() const
{
    glm::mat4 translate = glm::translate(glm::mat4(1.0f), position);
    glm::mat4 rotation = glm::toMat4(glm::quat(glm::radians(360.0f), 0, 1, 0));

    glm::mat4 matrix = translate * rotation;
    return matrix;
}

绘制实体时,这称为:

void DrawnEntity::render()
{
    if (enabled)
        mesh->render(getMatrix());
}

随后将其称为:

void Mesh::render(glm::mat4 matrix)
{
    glUseProgram(shaderID);
    vao->render(matrix);
}

vao是一个VertexArrayObject,这是函数:

void VertexArrayObject::render(glm::mat4 matrix)
{
    GLuint uModel = glGetUniformLocation(shaderID, "uModel");
    glUniformMatrix4fv(uModel, 1, GL_TRUE, &matrix[0][0]);
    glBindVertexArray(vao[0]);
    glDrawArrays(GL_TRIANGLES, 0, mesh->vertexCount());
    glBindVertexArray(0);
}

忽略旋转,似乎所有顶点都正确加载。对于它的价值,这是生成立方体的类:

#include "CubeMesh.h"
#include "../VertexArrayObject.h"

CubeMesh::CubeMesh(GLuint shader)
{
    shaderID = shader;
    glUseProgram(shaderID);
    generateFaces();
    vao = new VertexArrayObject(this);
}

void CubeMesh::generateFaces()
{
    // Front face
    generateFace(glm::vec3(-0.5, 0.5, 0.5), glm::vec3(0.5, -0.5, 0.5));
    // Left face
    generateFace(glm::vec3(-0.5, -0.5, 0.5), glm::vec3(-0.5, 0.5, -0.5));
    // Back face
    generateFace2(glm::vec3(0.5, -0.5, -0.5), glm::vec3(-0.5, 0.5, -0.5));
    // Right face
    generateFace2(glm::vec3(0.5, -0.5, 0.5), glm::vec3(0.5, 0.5, -0.5));
}

void CubeMesh::generateFace(glm::vec3 point1, glm::vec3 point2)
{
    glm::vec3 tl = point1;
    glm::vec3 br = point2;
    glm::vec3 tr = glm::vec3(br.x, tl.y, br.z);
    glm::vec3 bl = glm::vec3(tl.x, br.y, tl.z);

    Vertex f1v1(glm::vec3(tl.x, tl.y, tl.z));
    Vertex f1v2(glm::vec3(bl.x, bl.y, bl.z));
    Vertex f1v3(glm::vec3(br.x, br.y, br.z));
    Triangle f1(f1v1, f1v2, f1v3);

    Vertex f2v1(glm::vec3(tr.x, tr.y, tr.z));
    Vertex f2v2(glm::vec3(tl.x, tl.y, tl.z));
    Vertex f2v3(glm::vec3(br.x, br.y, br.z));
    Triangle f2(f2v1, f2v2, f2v3);

    addData(f1);
    addData(f2);
}

void CubeMesh::generateFace2(glm::vec3 point1, glm::vec3 point2)
{
    glm::vec3 tl = point1;
    glm::vec3 br = point2;
    glm::vec3 tr = glm::vec3(br.x, tl.y, br.z);
    glm::vec3 bl = glm::vec3(tl.x, br.y, tl.z);

    Vertex f1v1(glm::vec3(tl.x, tl.y, tl.z));
    Vertex f1v2(glm::vec3(br.x, br.y, br.z));
    Vertex f1v3(glm::vec3(bl.x, bl.y, bl.z));
    Triangle f1(f1v1, f1v2, f1v3);

    Vertex f2v1(glm::vec3(tr.x, tr.y, tr.z));
    Vertex f2v2(glm::vec3(br.x, br.y, br.z));
    Vertex f2v3(glm::vec3(tl.x, tl.y, tl.z));
    Triangle f2(f2v1, f2v2, f2v3);

    addData(f1);
    addData(f2);
}

顶点着色器如下:

#version 430 core

uniform mat4 uModel;
uniform mat4 uView;
uniform mat4 uProjection;

in vec3 vPosition;
in vec3 vNormal;

out vec4 oColour;

void main(void)
{   
    oColour = vec4(vPosition, 1);
    gl_Position = vec4(vPosition, 1) * uModel * uView * uProjection;
}

uModel是表示单个模型平移,旋转等的矩阵.uView是摄像机的位置,uProjection是投影矩阵。第一个被送到前面显示的VertexArrayObject中的着色器,而最后两个被送到相机对象中的着色器,如下所示:

void Camera::initialise()
{
    glUseProgram(shaderID);

    view = glm::translate(glm::mat4(1), position);

    int uView = glGetUniformLocation(shaderID, "uView");
    glUniformMatrix4fv(uView, 1, GL_TRUE, &view[0][0]);

    int uProjection = glGetUniformLocation(shaderID, "uProjection");
    glm::mat4 projection = glm::perspective(1.0, (double)1024 / (double)1024, 0.01, 10.0);
    glUniformMatrix4fv(uProjection, 1, GL_TRUE, &projection[0][0]);
}

模型的位置为0 0 0,摄像机的位置为0 0 -5。当uModel位置发生变化时,立方体会被渲染到预期的位置,但是旋转它不会发挥作用。

任何人都可以看到我可能做错的事吗?还有你需要看的代码吗?

1 个答案:

答案 0 :(得分:0)

我发现更改了以下行:

glm::mat4 rotation = glm::toMat4(glm::quat(glm::radians(360.0f), 0, 1, 0));

到此:

glm::mat4 rotation = glm::rotate(translate, (float)glm::radians(0.0), glm::vec3(0.0f, 1.0f, 0.0f));

解决了这个问题。我无法解释为什么第一个没有工作,因为我对Quaternion的评论不够充分。如果有人能更好地解释,请编辑我的答案。无论如何,这是我能找到的最佳解决方案。