请求提供在Qt3D的basicshapes-cpp中集成QClipPlane的可行示例代码
在Qt3D basicshapes-cpp中集成QClipPlane的正确方法
核心结论
QClipPlane作为渲染状态,需要通过帧图(FrameGraph)节点全局应用,或作为单个实体的组件局部应用。你之前出现窗口空白的问题,主要是因为未正确设置平面方程,且未将渲染状态关联到正确的渲染路径上。
全局裁剪(所有形状生效)
修改main.cpp中帧图的创建逻辑,将QClipPlane封装到QRenderStateSet,并插入到帧图的渲染流程中:
#include <Qt3DRender/QClipPlane> #include <Qt3DRender/QRenderStateSet> // ... 原有代码 int main(int argc, char* argv[]) { QApplication app(argc, argv); Qt3DExtras::Qt3DWindow view; // 创建根实体 Qt3DCore::QEntity *rootEntity = new Qt3DCore::QEntity(); view.setRootEntity(rootEntity); // ... 原有创建相机、光源、各种形状的代码 // 重构帧图,添加裁剪平面 Qt3DRender::QRenderSurfaceSelector *surfaceSelector = new Qt3DRender::QRenderSurfaceSelector(rootEntity); Qt3DRender::QViewport *viewport = new Qt3DRender::QViewport(surfaceSelector); viewport->setNormalizedRect(QRectF(0.0, 0.0, 1.0, 1.0)); // 1. 创建渲染状态集合,用于存放裁剪平面 Qt3DRender::QRenderStateSet *clipStateSet = new Qt3DRender::QRenderStateSet(viewport); // 2. 创建裁剪平面,设置平面方程:Ax + By + Cz + D = 0 // 示例:裁剪x < 0.5的区域,对应方程x - 0.5 = 0 → 参数(1,0,0,-0.5) Qt3DRender::QClipPlane *clipPlane = new Qt3DRender::QClipPlane(); clipPlane->setPlane(QVector4D(1.0f, 0.0f, 0.0f, -0.5f)); clipPlane->setEnabled(true); // 3. 将裁剪平面添加到渲染状态集合 clipStateSet->addRenderState(clipPlane); // 4. 将清缓冲节点挂到裁剪状态集合下,确保渲染流程正确 Qt3DRender::QClearBuffers *clearBuffers = new Qt3DRender::QClearBuffers(clipStateSet); clearBuffers->setBuffers(Qt3DRender::QClearBuffers::ColorDepthBuffer); // ... 原有显示窗口的代码 view.show(); return app.exec(); }
局部裁剪(仅单个形状生效)
如果只需要裁剪特定形状(比如 torus),给目标实体添加QRenderStateSet组件即可:
// 创建torus实体时添加 Qt3DCore::QEntity *torusEntity = new Qt3DCore::QEntity(rootEntity); Qt3DExtras::QTorusMesh *torusMesh = new Qt3DExtras::QTorusMesh(); // ... 原有设置torusMesh参数的代码 Qt3DExtras::QPhongMaterial *torusMaterial = new Qt3DExtras::QPhongMaterial(); // ... 原有设置材质的代码 // 添加裁剪状态组件 Qt3DRender::QRenderStateSet *torusClipState = new Qt3DRender::QRenderStateSet(); Qt3DRender::QClipPlane *torusClipPlane = new Qt3DRender::QClipPlane(); // 示例:裁剪y < 0的区域,方程y = 0 → 参数(0,1,0,0) torusClipPlane->setPlane(QVector4D(0.0f, 1.0f, 0.0f, 0.0f)); torusClipState->addRenderState(torusClipPlane); // 将所有组件添加到torus实体 torusEntity->addComponent(torusMesh); torusEntity->addComponent(torusMaterial); torusEntity->addComponent(torusTransform); torusEntity->addComponent(torusClipState); // 新增这一行
关键注意点
- 平面方程参数:
QVector4D(A,B,C,D)对应Ax + By + Cz + D = 0,参数方向决定裁剪哪一侧的几何体。 - 全局裁剪必须关联到帧图节点,确保渲染管线在绘制所有物体前应用该状态。
- 局部裁剪需将RenderStateSet作为实体的组件添加,仅影响该实体及其子实体。
内容的提问来源于stack exchange,提问作者HarryP2023
相关产品推荐
相关产品推荐

