QT3D 中的二维网格

2D meshes in QT3D

在我看来,Qt3D 不能很好地渲染 2D 网格。要明白我的意思,请打开 shadow map QML example 并将相机控制器从 FirstPersonCameraController 更改为 OrbitCameraController。 运行 程序并尝试从下方查看地平面,您会看到它消失了。所以 QT3D 只是从一侧渲染 2D 网格并使它们从另一侧透明。

我该如何解决这个问题?即从两侧渲染 2D 网格?

编辑: 现在我知道我必须禁用剔除才能使渲染工作。我想到了这一点:

//'this' refers to Qt3DWindow
rootEntity->addComponent(this->renderSettings());
QCullFace *face = new QCullFace();
QRenderStateSet *stateSet = new QRenderStateSet(this->renderSettings()->activeFrameGraph());
QRenderSurfaceSelector *selector = new QRenderSurfaceSelector(this->renderSettings());
face->setMode(QCullFace::NoCulling);
stateSet->addRenderState(face);
selector->setSurface(this);

但这似乎仍然没有改变任何东西。我错过了什么吗?

这是一个最低限度的工作示例:

main.cpp:

#include <QApplication>
#include "clickwindow.h"

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    GraphicsWindow graphicsWindow;
    graphicsWindow.show();
    return a.exec();
}

graphicswindow.h:

#include <Qt3DExtras/Qt3DWindow>
#include <Qt3DCore/QEntity>
#include <Qt3DCore/QTransform>

class GraphicsWindow : public Qt3DExtras::Qt3DWindow {
public:
    GraphicsWindow();
    void wheelEvent ( QWheelEvent * event ) override;

private:
    Qt3DCore::QEntity *createScene();
    Qt3DCore::QTransform *planeTransform;
};

graphicswindow.cpp:

#include "graphicswindow.h"
#include <QMouseEvent>
#include <Qt3DRender/QViewport>
#include <Qt3DRender/QClearBuffers>
#include <Qt3DRender/QRenderSurfaceSelector>
#include <Qt3DRender/QRenderStateSet>
#include <Qt3DRender/QCullFace>
#include <Qt3DRender/QCameraSelector>
#include <Qt3DRender/QCamera>
#include <Qt3DRender/QMaterial>
#include <Qt3DExtras/QGoochMaterial>
#include <Qt3DExtras/QPlaneMesh>
#include <Qt3DRender/QDepthTest>

GraphicsWindow::GraphicsWindow() : Qt3DExtras::Qt3DWindow() {
    Qt3DRender::QCamera *camera = this->camera();
    camera->lens()->setPerspectiveProjection(45.0f, 16.0f/9.0f, 0.1f, 1000.0f);
    camera->setPosition(QVector3D(20.0, 20.0, 20.0f));
    camera->setViewCenter(QVector3D(0, 0, 0));

    Qt3DRender::QRenderSurfaceSelector *surfaceSelector = new Qt3DRender::QRenderSurfaceSelector;
    surfaceSelector->setSurface(this);
    Qt3DRender::QViewport *viewport = new Qt3DRender::QViewport(surfaceSelector);
    viewport->setNormalizedRect(QRectF(0, 0, 1.0, 1.0));
    Qt3DRender::QCameraSelector *cameraSelector = new Qt3DRender::QCameraSelector(viewport);
    cameraSelector->setCamera(camera);
    Qt3DRender::QClearBuffers *clearBuffers = new Qt3DRender::QClearBuffers(cameraSelector);
    clearBuffers->setBuffers(Qt3DRender::QClearBuffers::ColorDepthBuffer);
    clearBuffers->setClearColor(Qt::white);
    Qt3DRender::QRenderStateSet *renderStateSet = new Qt3DRender::QRenderStateSet(clearBuffers);
    Qt3DRender::QCullFace *cullFace = new Qt3DRender::QCullFace(renderStateSet);
    cullFace->setMode(Qt3DRender::QCullFace::NoCulling);
    renderStateSet->addRenderState(cullFace);
    Qt3DRender::QDepthTest *depthTest = new Qt3DRender::QDepthTest;
    depthTest->setDepthFunction(Qt3DRender::QDepthTest::Less);
    renderStateSet->addRenderState(depthTest);
    setActiveFrameGraph(surfaceSelector);

    Qt3DCore::QEntity *root = createScene();
    setRootEntity(root);
}

void GraphicsWindow::wheelEvent(QWheelEvent *event) {
    planeTransform->setRotationZ(planeTransform->rotationZ() + event->delta() / 40.f);
}


Qt3DCore::QEntity* GraphicsWindow::createScene() { // Root entity
    Qt3DCore::QEntity *rootEntity = new Qt3DCore::QEntity;

    Qt3DCore::QEntity *planeEntity = new Qt3DCore::QEntity(rootEntity);
    Qt3DRender::QMaterial *meshMaterial = new Qt3DExtras::QGoochMaterial;
    Qt3DExtras::QPlaneMesh *planeMesh = new Qt3DExtras::QPlaneMesh;
    planeMesh->setHeight(10);
    planeMesh->setWidth(10);
    planeTransform = new Qt3DCore::QTransform;

    planeEntity->addComponent(planeTransform);
    planeEntity->addComponent(planeMesh);
    planeEntity->addComponent(meshMaterial);

    return rootEntity;
}

请记住,Qt3DWindowsetActiveFramegraph函数会自动在框架上添加window的renderSettings()函数返回的QRenderSettings您设置为活动框架图的图节点。如果您要实现自己的 3D window 或创建屏幕外渲染器,则必须使用 QRenderSettings 作为框架图的根节点(window 将其渲染设置设置为根节点的父节点您设置的帧图节点)并将渲染设置添加到实际的根节点,即作为帧图和场景图的父节点的节点。