9.绘制默认的工作平面

这一节我们将绘制默认的工作平面和当前的工作平面,并用网格线进行填充,这回用到我们此前介绍过的数据与渲染的桥梁VAO、VBO、EBO)相关知识。

9.1.在顶点着色器中添加世界坐标转换处理

由于OpenGL默认是y-up,我们开发的Viewer是z-up的,为了让Viewer达到正确效果,我们需要叠加y-up to z-up的转换矩阵。

//  y-up to z-up
m_modelMatrix = QMatrix4x4(1.0f, 0.0f, 0.0f, 0.0f,
    0.0f, 0.0f, -1.0f, 0.0f,
    0.0f, 1.0f, 0.0f, 0.0f,
    0.0f, 0.0f, 0.0f, 1.0f);//(1.0f);
m_modelMatrix = m_modelMatrix.transposed();

然后在渲染循环中传递给顶点着色器,

m_lightShader.setUniformValue("model", m_modelMatrix);

9.2.定义WorkPlanePara

我们定义类WorkPlanePara来表示工作平面,

class WorkPlanePara
{
public:
    WorkPlanePara(const Vector3f& ori, const Vector3f& norm, const Vector3f& lX, const Vector3f& lY, float halfLen, int cntGridPerEdg, float off)
        : origin(ori), normal(norm), localX(lX), localY(lY), halfLength(halfLen), gridCntPerEdge(cntGridPerEdg), offset(off)
    {
    }

    Vector3f origin;
    Vector3f normal;
    Vector3f localX;
    Vector3f localY;
    float halfLength;
    int gridCntPerEdge;
    float offset;
};

9.3.定义变量并进行工作

然后定义当前defaultWorkPlanecurrentWorkPlane,随后调用GetWorkPlaneMesh函数获取对应的mesh,之后添加到当前成员变量mapName2VMesh中, 在每个渲染循环中我们进行绘制。

void Model::setupWorkPlaneMesh()
{
    //  cube
    WorkPlanePara workPlane[2]{
        WorkPlanePara(Vector3f::Zero, Vector3f::BasicZ, Vector3f::BasicX, Vector3f::BasicY, 20000.0f, 10, -1.8f),
        WorkPlanePara(Vector3f::Zero, Vector3f::BasicZ, Vector3f::BasicX, Vector3f::BasicY, 1000.0f, 4, 0.0f) };

    for (size_t cntItem = 0; cntItem < 2; cntItem++)
    {
        TriangleMesh mesh;
        GetWorkPlaneMesh(workPlane[cntItem], mesh);

        auto& name = cntItem == 0 ? ViewerCache::defaultWorkPlane : ViewerCache::currentWorkPlane;
        //mapName2VMesh[name] = MeshInfo(ConvertMesh(mesh));
        mapName2VMesh.insert(make_pair(name, MeshInfo(ConvertMesh(mesh))));
    }
}

上述GetWorkPlaneMesh函数中,我们根据WorkPlanePara的参数构造mesh,包括尺寸、位置、方向以及网格线数量等。

void Model::drawWorkPlane(QOpenGLShaderProgram& shader)
{
    for (auto& meshInfo : mapName2VMesh)
    {
        shader.setUniformValue("objectColor", meshInfo.second.color.GetWX(), meshInfo.second.color.GetWY(), meshInfo.second.color.GetWZ(), meshInfo.second.color.GetW());
        meshInfo.second.current->Draw(shader);
    }
}

9.4.效果

提示:

详细请查看本节课程对应的代码工程,我们也用到了智能指针shared_ptr来管理堆上的资源(Mesh*), 如果有疑问欢迎交流~

如果一切正常,或者遇到的问题被排查解决,那么运行后可以看到如下效果。

绘制工作平面

图:绘制工作平面