c++ - QT3D 中的二维网格
问题描述
在我看来,Qt3D 不能很好地渲染 2D 网格。要了解我的意思,请打开阴影贴图 QML 示例并将相机控制器从 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;
}
请记住,该setActiveFramegraph
函数会Qt3DWindow
自动将窗口函数QRenderSettings
返回的值添加renderSettings()
到您设置为活动框架图的框架图节点上。如果您正在实现自己的 3D 窗口或创建和离屏渲染器,则必须QRenderSettings
将其用作框架图的根节点(窗口将其渲染设置设置为您设置的根框架图节点的父节点)并将渲染设置添加到实际的根节点,即作为框架图和场景图的父节点的节点。
推荐阅读
- bash - Docker 容器中的 Bash 脚本意外“权限被拒绝”
- .net - 在 .net Standard 上添加 WCF 连接服务的问题
- java - IntellijIDEA 看不到我的罐子,我该怎么办?
- python - 正则表达式,包括直到一个字符的所有内容,但忽略该字符的转义版本
- c++ - 如何添加到第 3 方库的路径?- 日食/阿杜诺
- sharepoint-online - 自定义 Sharepoint Online 下拉列表内容
- c# - 无法设置 DataGrid 虚拟化模式
- python - 当原始列表不会更改时,列表切片与使用指针
- ssl-certificate - 使用单独的 SSL 证书绑定多个站点
- python - 在 Python 中随机选择一个列表?